Aros/Developer/Docs/Libraries/Intuition/BOOPSIClasses
Introduction
editApart from RootClass, all classes that are written will inherit from this base class (rootclass). Your class must either implement the rootclass methods or defer processing of these methods to the next class.
rootclass
editThe rootclass method IDs:
OM_NEW | Create a new object. |
OM_DISPOSE | Delete an object. |
OM_SET | Change an object's attributes. |
OM_GET | Retrieve the value of one of the object's attributes. |
gadgetclass
editgadgetclass has to understand these rootclass methods and introduces these
GM_HITTEST | return GMR_GADGETHIT if you are clicked on |
GM_RENDER | draw yourself, in the appropriate state |
GM_GOACTIVE | you are now going to be fed input |
GM_HANDLEINPUT | handle that input |
GM_GOINACTIVE | whether or not by choice, you are done |
propgclass
editstrgclass
editbuttongclass
editgroupgclass
editimageClass
editBoopsi's imageclass is one of the standard classes built into Intuition. As its name implies, it is a class of Intuition Images. These boopsi images can be used in place of traditional Image structure (as they contain an Intuition Image structure), but they are much more powerful. By using boopsi methods, an application or Intuition can tell an imageclass object to render itself. Because it renders itself (rather than Intuition rendering it), the imageclass object is free to render whatever it wants (well, within reason). For example, a boopsi image object can render itself according to the current display resolution, or to scale itself to any size an application requests.
Imageclass defines several methods of its own which subclasses of imageclass either have to implement or pass on to their superclass.
IM_DRAW IM_HITTEST IM_ERASEFRAME IM_MOVE IM_ERASE IM_DRAWFRAME IM_HITFRAME IM_FRAMEBOX
You create a new boopsi class which is subclass of Intuition's IMAGECLASS (like this bitmap class) and in the IM_DRAW method you do the painting in whatever way you want. If you have some Bitmap from the datatype object use that with BltBitMapRastPort(), if you have some chunky pixel array, use WritePixelArray().
See compiler/coolimages/imageclass.c
Objects created from classes derived from IMAGECLASS can be passed to DrawImage().
You can use objects from IMAGECLASS (or subclasses from IMAGECLASS) as GadgetRender (etc.) in gadgets (no matter if the gadget is old-style or boopsi). You can also cast the object to (struct Image *), because the instance data contains a struct Image at the beginning.
This new image class I'm talking about is not different to what you are already doing on AOS (using the Reaction/Classact bitmap.image class which is also a subclass of IMAGECLASS). AROS doesn't have that class so one would either need to write it (it's an external class similar to colorwheel.gadget), or write a simplified class reimplementation directly in your program == the new image class I mean which doesn't need to do much more than some blitting with BltBitMapRastPort() or similar in IM_DRAW (if you are already loading the image/datatype object elsewhere, otherwise you could also do the loading in the new image class's OM_NEW).
frameiclass
editsysiclass
editfillrectclass
editExamples
editThe following worked with a 4 color IFF image. I'm assuming that I can do CopyMem for the planes of a V42 datatype bitmap.
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/graphics.h>
#include <proto/intuition.h>
#include <proto/datatypes.h>
#include <datatypes/pictureclass.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
static struct Window *window;
static struct RastPort *win_rp;
static struct Image *img;
static struct Image *load_image(CONST_STRPTR);
static void clean_exit(CONST_STRPTR s);
static void handle_events(void);
int main(void)
{
window = OpenWindowTags(NULL,
WA_Left, 50,
WA_Top, 70,
WA_Width, 400,
WA_Height, 350,
WA_Title, "Load Image",
WA_Activate, TRUE,
WA_SmartRefresh, TRUE,
WA_NoCareRefresh, TRUE,
WA_GimmeZeroZero, TRUE,
WA_CloseGadget, TRUE,
WA_DragBar, TRUE,
WA_DepthGadget, TRUE,
WA_IDCMP, IDCMP_CLOSEWINDOW,
TAG_END);
if (! window) clean_exit("Can't open windown");
win_rp = window->RPort;
img = load_image("test.iff");
DrawImage(win_rp, img, 50, 50);
handle_events();
clean_exit(NULL);
return 0;
}
static struct Image *load_image(CONST_STRPTR name)
{
struct Image *newimage = NULL;
UBYTE *pixeldata = NULL;
Object *dto = NULL;
struct BitMapHeader *bmh = NULL;
struct BitMap *bm = NULL;
WORD width, height, depth;
LONG size;
if ((dto = NewDTObject((APTR)name,
PDTA_Remap, FALSE,
PDTA_DestMode, PMODE_V42,
TAG_DONE)) == NULL)
{
puts("Can't open datatype");
goto cleanup;
}
if (GetDTAttrs(dto, PDTA_BitMapHeader, &bmh, PDTA_BitMap, &bm, TAG_DONE) != 2)
{
puts("Can't get bitmapheader and bitmap");
goto cleanup;
}
width = bmh->bmh_Width;
height = bmh->bmh_Height;
depth = bmh->bmh_Depth;
size = ((width + 16) / 16) * height * depth * 2; // Bytes
printf("width %d height %d depth %d size %dn", width, height, depth, size);
if ((pixeldata = AllocVec(size, MEMF_ANY)) == NULL)
{
puts("Can't allocate memory for pixeldata");
goto cleanup;
}
if ((newimage = AllocVec(sizeof (struct Image), MEMF_ANY | MEMF_CLEAR)) == NULL)
{
puts("Can't allocate memory for struct Image");
goto cleanup;
}
WORD blocksize = ((width + 16) / 16) * height * 2;
UBYTE *ptr = pixeldata;
UBYTE d;
for (d = 0; d < depth; d++)
{
CopyMem(bm->Planes[d], ptr, blocksize);
ptr += blocksize;
}
newimage->ImageData = pixeldata;
newimage->Width = width;
newimage->Height = height;
newimage->PlanePick = (1 << depth) - 1;
newimage->Depth = depth;
if (dto) DisposeDTObject(dto);
return newimage;
cleanup:
FreeVec(pixeldata);
FreeVec(newimage);
if (dto) DisposeDTObject(dto);
return NULL;
}
static void handle_events(void)
{
struct IntuiMessage *imsg;
struct MsgPort *port = window->UserPort;
BOOL terminated = FALSE;
while (!terminated)
{
Wait(1L << port->mp_SigBit);
if ((imsg = (struct IntuiMessage *)GetMsg(port)) != NULL)
{
switch (imsg->Class)
{
case IDCMP_CLOSEWINDOW:
terminated = TRUE;
break;
}
ReplyMsg((struct Message *)imsg);
}
}
}
static void clean_exit(CONST_STRPTR s)
{
if (s) PutStr(s);
FreeVec(img->ImageData);
FreeVec(img);
if (window) CloseWindow(window);
exit(0);
}
icclass
editmust understand rootclass method IDs but also these
ICM_SETLOOP ICM_CLEARLOOP ICM_CHECKLOOP - to manage a loop inhibition for broadcasted messages. They increment, decrement, and return the value of that counter
ICA_Target ICA_Map