Aros/開發者/文件/庫/Intuition/BOOPSIClasses
除了 RootClass 之外,所有編寫的類都將繼承自此基類(rootclass)。您的類必須實現 rootclass 方法,或將這些方法的處理延遲到下一個類。
rootclass 方法 ID
| OM_NEW | 建立新物件。 |
| OM_DISPOSE | 刪除物件。 |
| OM_SET | 更改物件的屬性。 |
| OM_GET | 檢索物件的屬性值。 |
gadgetclass 必須理解這些 rootclass 方法,並引入以下方法:
| GM_HITTEST | 如果被點選,則返回 GMR_GADGETHIT |
| GM_RENDER | 繪製自身,處於適當的狀態 |
| GM_GOACTIVE | 您現在將接收輸入 |
| GM_HANDLEINPUT | 處理該輸入 |
| GM_GOINACTIVE | 無論是否出於選擇,您都已完成 |
Boopsi 的 imageclass 是 Intuition 內建的標準類之一。顧名思義,它是一類 Intuition 圖片。這些 boopsi 圖片可以替代傳統的 Image 結構(因為它們包含 Intuition Image 結構),但它們的功能更強大。透過使用 boopsi 方法,應用程式或 Intuition 可以告訴 imageclass 物件自行渲染。由於它是自行渲染(而不是 Intuition 為其渲染),因此 imageclass 物件可以自由地渲染它想要的任何內容(在合理的範圍內)。例如,boopsi 圖片物件可以根據當前顯示解析度自行渲染,或者根據應用程式請求的任何大小進行縮放。
Imageclass 定義了一些它自身的方法,imageclass 的子類必須實現這些方法或將其傳遞給它們的超類。
IM_DRAW IM_HITTEST IM_ERASEFRAME IM_MOVE IM_ERASE IM_DRAWFRAME IM_HITFRAME IM_FRAMEBOX
您建立了一個新的 boopsi 類,它是 Intuition 的 IMAGECLASS 的子類(例如這個點陣圖類),在 IM_DRAW 方法中,您可以以您想要的方式進行繪畫。如果您從資料型別物件中獲得了一些點陣圖,請使用 BltBitMapRastPort() 與其一起使用,如果您擁有某些塊狀畫素陣列,請使用 WritePixelArray()。
請參閱 compiler/coolimages/imageclass.c
從 IMAGECLASS 派生的類建立的物件可以傳遞給 DrawImage()。
您可以使用 IMAGECLASS 的物件(或 IMAGECLASS 的子類)作為小部件的 GadgetRender(等等)(無論該小部件是舊式小部件還是 boopsi 小部件)。您也可以將該物件強制轉換為 (struct Image *),因為例項資料在開頭包含一個 struct Image。
我所說的這種新的圖片類與您已經在 AOS 上所做的並不不同(使用 Reaction/Classact bitmap.image 類,它也是 IMAGECLASS 的子類)。AROS 沒有那個類,因此要麼需要編寫它(它是一個類似於 colorwheel.gadget 的外部類),要麼在您的程式中直接編寫一個簡化的類重新實現 == 我指的是新的圖片類,它不需要做太多,只需要在 IM_DRAW 中進行一些使用 BltBitMapRastPort() 或類似方法的 blitting(如果您已經在其他地方載入圖片/資料型別物件,否則您也可以在新圖片類的 OM_NEW 中進行載入)。
以下方法適用於 4 色 IFF 圖片。我假設我可以對 V42 資料型別點陣圖的平面進行 CopyMem 操作。
#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);
}
必須理解 rootclass 方法 ID,但也理解以下方法:
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