void amiga_init (char *dir) { if ((DefaultPubScreen = LockPubScreen (0)) == 0) exit (1); screen_ratio (DefaultPubScreen); char prog_name[256]; static char font_name[MAXFONTPATH]; char *font_desc, *name_ptr; static WORD pens[] = {-1}; static struct TextAttr font = {NULL, 0, FS_NORMAL, 0}; int window = 0; if (Icon == NULL) { if (GetProgramName (prog_name, 256)) Icon = GetDiskObject (prog_name); } if (Icon) { if (FindToolType (Icon->do_ToolTypes, "WINDOW")) window = 1; if (font_desc = FindToolType (Icon->do_ToolTypes, "FONT")) { strcpy (font_name, font_desc); if (name_ptr = strrchr (font_name, '/')) { font.ta_Name = font_name; font.ta_YSize = atoi (name_ptr + 1); strcpy (name_ptr, ".font"); } } if (font.ta_Name) Font = OpenDiskFont (&font); } if (Font == NULL) { font.ta_Name = "topaz.font"; font.ta_YSize = 8; Font = OpenFont (&font); } if (window == 0) { if ((Screen = OpenScreenTags (0, SA_Pens, pens, SA_DisplayID, GetVPModeID (&DefaultPubScreen->ViewPort), SA_Overscan, OSCAN_TEXT, SA_Depth, 2, SA_Type, CUSTOMSCREEN | AUTOSCROLL, SA_Font, &font, SA_Title, TitleBar, TAG_DONE)) == 0) exit (1); } if ((Window = OpenWindowTags (0, WA_Left, 0, WA_Top, Screen ? 2 : DefaultPubScreen->BarHeight + 1, WA_Width, Screen ? Screen->Width : ScreenWidth, WA_Height, Screen ? Screen->Height - 2 : ScreenHeight - DefaultPubScreen->BarHeight - 1, WA_SmartRefresh, 1, WA_NewLookMenus, 1, WA_AutoAdjust, 1, WA_Borderless, Screen ? 1 : 0, WA_Backdrop, Screen ? 1 : 0, WA_Activate, 1, WA_CloseGadget, Screen ? 0 : 1, WA_DragBar, Screen ? 0 : 1, WA_DepthGadget, Screen ? 0 : 1, WA_SizeGadget, Screen ? 0 : 1, WA_SizeBBottom, Screen ? 0 : 1, WA_Title, TitleBar, WA_ScreenTitle, TitleBar, WA_IDCMP, IDCMP_RAWKEY | IDCMP_VANILLAKEY | IDCMP_MENUPICK | IDCMP_CLOSEWINDOW | IDCMP_CHANGEWINDOW, Screen ? WA_CustomScreen : WA_PubScreen, Screen ? Screen : DefaultPubScreen, TAG_DONE)) == 0) exit (1); ThisProcess = (struct Process *)FindTask(0); OldWindowPtr = ThisProcess->pr_WindowPtr; ThisProcess->pr_WindowPtr = Window; if ((Visual = GetVisualInfo (Window->WScreen, TAG_DONE)) == 0) exit (1); if ((Menus = CreateMenus (NewMenus, GTMN_NewLookMenus, TRUE, TAG_DONE)) == 0) exit (1); LayoutMenus (Menus, Visual, GTMN_NewLookMenus, TRUE, TAG_DONE); SetMenuStrip (Window, Menus); if ((GameReq = alloc_freq (dir)) == 0) exit (1); if ((SaveReq = alloc_freq (dir)) == 0) exit (1); if ((ScriptReq = alloc_freq (dir)) == 0) exit (1); RastPort = Window->RPort; SetDrMd (RastPort, JAM2); SetAPen (RastPort, 1); SetBPen (RastPort, 0); SetFont (RastPort, Font); DisplayHeight = ((Window->Height - Window->BorderTop - Window->BorderBottom) / RastPort->TxHeight) - 1; PreviousHeight = DisplayHeight; reset_cursor (); }
CDebugscreen::CDebugscreen() { Rows = 1; pFont = OpenFont("Data/verdana.ttf", 15, true); DebugItem FPS_Word; // Die FPS-Anzeige, hier das Wort "FPS" wird erzeugt und in die Map geschrieben FPS_Word.pTextObject->SetFont(pFont); FPS_Word.pTextObject->SetContent("FPS:"); FPS_Word.pTextObject->SetColor(255, 255, 255); FPS_Word.pTextObject->SetPos(1800, 13); FPS_Word.visible = true; FPS_Word.fTime = 0.0f; FPS_Word.always = true; Messages["FPS:"] = FPS_Word; DebugItem FPS; // Die eigentliche FPS-Zahl wird erzeugt und mit 0 initialisiert FPS.pTextObject->SetFont(pFont); FPS.pTextObject->SetContent("0"); FPS.pTextObject->SetColor(255, 255, 255); FPS.pTextObject->SetPos(1840, 13); FPS.visible = true; FPS.fTime = 0.0f; FPS.always = true; Messages["FPS"] = FPS; }
CursorPtr CreateRootCursor(char *unused1, unsigned int unused2) { CursorPtr curs; FontPtr cursorfont; int err; XID fontID; fontID = FakeClientID(0); err = OpenFont(serverClient, fontID, FontLoadAll | FontOpenSync, (unsigned)strlen(defaultCursorFont), defaultCursorFont); if (err != Success) return NullCursor; err = dixLookupResourceByType((pointer *)&cursorfont, fontID, RT_FONT, serverClient, DixReadAccess); if (err != Success) return NullCursor; if (AllocGlyphCursor(fontID, 0, fontID, 1, 0, 0, 0, ~0, ~0, ~0, &curs, serverClient, (XID)0) != Success) return NullCursor; if (!AddResource(FakeClientID(0), RT_CURSOR, (pointer)curs)) return NullCursor; return curs; }
int main(int argc, char **argv) { OpenScreen(); // SetOrientation int sw = ScreenWidth(); int sh = ScreenHeight(); fprintf(stderr, "[%ix%i]\n", sw, sh); if (sw >= 1200 || sh >= 1200) { cpar = ¶ms[1]; } else { cpar = ¶ms[0]; } cal_title_font = OpenFont(DEFAULTFONTB, cpar->tfontsize, 1); cal_month_font = OpenFont(DEFAULTFONTB, cpar->mfontsize, 1); cal_day_font = OpenFont(DEFAULTFONTB, cpar->dfontsize - (IsRTL() ? 2 : 0), 1); cal_date_font = OpenFont(DEFAULTFONT, cpar->dfontsize, 1); cal_date2_font = OpenFont(DEFAULTFONTB, cpar->dfontsize, 1); CurTime=time(NULL); CurDate=localtime(&CurTime); if (year>CurDate->tm_year+1900) step=-step; FirstDay=MilleniumFirstDay; while (year!=CurDate->tm_year+1900) { if (year%4==0) LongYear=1; else LongYear=0; if (LongYear && year%100==0 && year%400!=0) LongYear=0; FirstDay=(FirstDay+365*(1-LongYear)+366*LongYear)%7; year+=step; } InkViewMain(calendar_handler); return 0; }
static int MUIMasterInit(LIBBASETYPEPTR lh) { MUIMasterBase = (struct Library *)lh; InitSemaphore(&MUIMB(lh)->ZuneSemaphore); NewList((struct List *)&MUIMB(lh)->BuiltinClasses); NewList((struct List *)&MUIMB(lh)->Applications); ((struct MUIMasterBase_intern *)MUIMasterBase)->topaz8font = OpenFont(&topaz8Attr); return TRUE; }
Object *AROSCycle__OM_NEW(Class *cl, Class *rootcl, struct opSet *msg) { struct CycleData *data; struct TextAttr *tattr; struct TagItem imgtags[] = { { IA_Width , 0 }, { IA_Height , 0 }, { IA_EdgesOnly , FALSE }, { IA_FrameType , FRAME_BUTTON }, { TAG_DONE , 0UL } }; STRPTR *labels; Object *o; o = (Object *)DoSuperMethodA(cl, (Object *)rootcl, (Msg)msg); if (!o) return NULL; data = INST_DATA(cl, o); data->active = GetTagData(AROSCYCLE_Active, 0, msg->ops_AttrList); data->labels = (STRPTR *)GetTagData(AROSCYCLE_Labels, (IPTR) NULL, msg->ops_AttrList); data->numlabels = 0; labels = data->labels; if (labels) { while (labels[0]) { data->numlabels++; labels++; } } tattr = (struct TextAttr *)GetTagData(GA_TextAttr, (IPTR) NULL, msg->ops_AttrList); if (tattr) data->font = OpenFont(tattr); imgtags[0].ti_Data = (IPTR)EG(o)->Width; imgtags[1].ti_Data = (IPTR)EG(o)->Height; EG(o)->GadgetRender = NewObjectA(NULL, FRAMEICLASS, imgtags); if (!EG(o)->GadgetRender) { IPTR methodid = OM_DISPOSE; CoerceMethodA(cl, o, (Msg)&methodid); return NULL; } return o; }
balda_keyboard_view_t* balda_keyboard_view_init(balda_view_t* view, balda_bool has_cancel_button) { balda_keyboard_view_t* kb = (balda_keyboard_view_t*)malloc(sizeof(balda_keyboard_view_t)); kb->view = view; kb->keyboard = 0; kb->selected = 0; kb->font = OpenFont("LiberationSans-Bold", 28, 0); kb->has_cancel_button = has_cancel_button; kb->l = (ScreenWidth() - BALDA_VIEW_KEYBOARD_CELL_W * BALDA_VIEW_KEYBOARD_W - BALDA_VIEW_KEYBOARD_CELL_PADDING * (BALDA_VIEW_KEYBOARD_W - 1)) / 2; return kb; }
static BOOL LayOutReq (struct AHIAudioModeRequesterExt *req, struct TextAttr *TextAttr) { struct Gadget *gad; struct NewGadget ng; struct TextAttr *gadtextattr; struct TextFont *font; LONG fontwidth,buttonheight,buttonwidth,pixels; struct IntuiText intuitext = {1,0,JAM1,0,0,NULL,NULL,NULL}; LONG sliderlevels,sliderlevel; LONG selected; selected=GetSelected(req); GetSliderAttrs(req,&sliderlevels,&sliderlevel); // Calculate gadget area req->gx=req->Window->BorderLeft+4; req->gy=req->Window->BorderTop+2; req->gw=req->Window->Width-req->gx-(req->Window->BorderRight+4); req->gh=req->Window->Height-req->gy-(req->Window->BorderBottom+2); if(req->Gadgets) { RemoveGList(req->Window,req->Gadgets,-1); FreeGadgets(req->Gadgets); SetAPen(req->Window->RPort,0); SetDrMd(req->Window->RPort,JAM1); EraseRect(req->Window->RPort, req->Window->BorderLeft, req->Window->BorderTop, req->Window->Width-req->Window->BorderRight-1,req->Window->Height-req->Window->BorderBottom-1); RefreshWindowFrame(req->Window); } req->Gadgets=NULL; if((gad=CreateContext(&req->Gadgets))) { if(TextAttr) gadtextattr=TextAttr; else gadtextattr=req->Window->WScreen->Font; if((font=OpenFont(gadtextattr))) { fontwidth=font->tf_XSize; CloseFont(font); } else return FALSE; buttonheight=gadtextattr->ta_YSize+6; intuitext.ITextFont=gadtextattr; intuitext.IText=req->PositiveText; buttonwidth=IntuiTextLength(&intuitext); intuitext.IText=req->NegativeText; pixels=IntuiTextLength(&intuitext); buttonwidth=max(pixels,buttonwidth); buttonwidth+=4+fontwidth; // Create gadgets and check if they fit // Do the two buttons fit? if(2*buttonwidth > req->gw) return FALSE; ng.ng_TextAttr=gadtextattr; ng.ng_VisualInfo=req->vi; ng.ng_UserData=req; // OK button ng.ng_LeftEdge=req->gx; ng.ng_TopEdge=req->gy+req->gh-buttonheight; ng.ng_Width=buttonwidth; ng.ng_Height=buttonheight; ng.ng_GadgetText=req->PositiveText; ng.ng_GadgetID=OKBUTTON; ng.ng_Flags=PLACETEXT_IN; gad=CreateGadget(BUTTON_KIND,gad,&ng,TAG_END); // Cancel button ng.ng_LeftEdge=req->gx+req->gw-ng.ng_Width; ng.ng_GadgetText=req->NegativeText; ng.ng_GadgetID=CANCELBUTTON; gad=CreateGadget(BUTTON_KIND,gad,&ng,TAG_END); // Frequency if(req->Flags & freqgad) { intuitext.IText = GetString(msgReqFrequency, req->Catalog); pixels=IntuiTextLength(&intuitext)+INTERWIDTH; if(pixels+MINSLIDERWIDTH+INTERWIDTH+FREQLEN2*fontwidth > req->gw) return FALSE; ng.ng_Width=req->gw-pixels-INTERWIDTH-FREQLEN2*fontwidth; ng.ng_LeftEdge=req->gx+pixels; ng.ng_TopEdge-=2+buttonheight; ng.ng_GadgetText = GetString(msgReqFrequency, req->Catalog); ng.ng_GadgetID=FREQSLIDER; ng.ng_Flags=PLACETEXT_LEFT; gad=CreateGadget(SLIDER_KIND,gad,&ng, GTSL_Min,0, GTSL_Max,sliderlevels-1, GTSL_Level,sliderlevel, GTSL_LevelFormat, (ULONG) FREQTEXT2, GTSL_MaxLevelLen,FREQLEN2, GTSL_LevelPlace,PLACETEXT_RIGHT, GTSL_DispFunc, (ULONG) m68k_IndexToFrequency, GA_RelVerify,TRUE, GA_Disabled,!sliderlevels || (req->tempAudioID == AHI_DEFAULT_ID), TAG_DONE); req->slidergadget=gad; // Save for HadleReq()... } // ListView if((ng.ng_Height=ng.ng_TopEdge-2-req->gy) < buttonheight) return FALSE; ng.ng_LeftEdge=req->gx; ng.ng_TopEdge=req->gy; ng.ng_Width=req->gw; ng.ng_GadgetText=NULL, ng.ng_GadgetID=LISTVIEW; ng.ng_Flags=PLACETEXT_ABOVE; gad=CreateGadget(LISTVIEW_KIND,gad,&ng, GTLV_ScrollWidth,(fontwidth>8 ? fontwidth*2 : 18), GTLV_Labels, (ULONG) req->list, GTLV_ShowSelected,NULL, ((selected == ~0) || (GadToolsBase->lib_Version >= 39) ? TAG_IGNORE : GTLV_Top),selected, (selected == ~0 ? TAG_IGNORE : GTLV_MakeVisible),selected, GTLV_Selected,selected, TAG_DONE); req->listviewgadget=gad; // Save for HadleReq()... if(!gad) return FALSE; } else return FALSE; AddGList(req->Window,req->Gadgets,~0,-1,NULL); RefreshGList(req->Gadgets,req->Window,NULL,-1); GT_RefreshWindow(req->Window,NULL); return TRUE; }
BOOL layoutmenuitems(struct MenuItem * firstitem, struct VisualInfo * vi, struct TagItem * taglist, struct GadToolsBase_intern * GadToolsBase) { struct Menu * menu; struct MenuItem * menuitem = firstitem; struct MenuItem * equalizeitem = firstitem; struct Image * amikeyimage, * chkimage; struct TextExtent te; ULONG curX = 0; ULONG curY = 0; WORD numcolumns = 1; amikeyimage = (struct Image *)GetTagData(GTMN_AmigaKey, 0, taglist); if (!amikeyimage) amikeyimage = vi->vi_dri->dri_AmigaKey; chkimage = (struct Image *)GetTagData(GTMN_Checkmark, 0, taglist); if (!chkimage) chkimage = vi->vi_dri->dri_CheckMark; FontExtent(vi->vi_dri->dri_Font, &te); while (NULL != menuitem) { ULONG addwidth = 0; ULONG addleft = 0; menuitem->LeftEdge = curX; menuitem->TopEdge = curY; if (0 != (menuitem->Flags & CHECKIT)) { /* ** A checkmark will appear on the left. */ addleft += chkimage->Width + CHECKMARK_TEXT_SPACING; addwidth += chkimage->Width + CHECKMARK_TEXT_SPACING; } if (0 != (menuitem->Flags & ITEMTEXT)) { /* ** Text */ struct IntuiText * it = (struct IntuiText *)menuitem->ItemFill; struct TagItem * ti; if (NULL == it) return FALSE; if (NULL != (ti = FindTagItem(GTMN_FrontPen, taglist))) { it->FrontPen = ti->ti_Data; } else { it->FrontPen = vi->vi_dri->dri_Pens[BARDETAILPEN]; } it->ITextFont = (struct TextAttr *)GetTagData(GTMN_TextAttr, 0, taglist); it->LeftEdge = ITEXT_EXTRA_LEFT + addleft; it->TopEdge = ITEXT_EXTRA_TOP; menuitem->Width = MyIntuiTextLength(vi, it, GadToolsBase) + addwidth + ITEXT_EXTRA_LEFT + ITEXT_EXTRA_RIGHT; /* ** Calculate the height menu item. */ if (NULL == it->ITextFont) { /* ** No font is provided, so I will work with the screen font. */ menuitem->Height = vi->vi_dri->dri_Font->tf_YSize + ITEXT_EXTRA_TOP + ITEXT_EXTRA_BOTTOM; } else { struct TextFont * font; if (NULL != (font = OpenFont(it->ITextFont))) { menuitem->Height = font->tf_YSize + ITEXT_EXTRA_TOP + ITEXT_EXTRA_BOTTOM; CloseFont(font); } else return FALSE; } } /* if (0 != (menuitem->Flags & ITEMTEXT)) */ else { /* ** Image */ struct Image * im = (struct Image *)menuitem->ItemFill; if (NULL == im) return FALSE; if (is_menubarlabelclass_image(im, GadToolsBase)) { menuitem->Width = 10; menuitem->Height = 7; } else { menuitem->Width = im->Width + addwidth + IMAGE_EXTRA_LEFT + IMAGE_EXTRA_RIGHT; menuitem->Height = im->Height + IMAGE_EXTRA_TOP + IMAGE_EXTRA_BOTTOM; im->LeftEdge = IMAGE_EXTRA_LEFT + addleft; im->TopEdge = IMAGE_EXTRA_TOP; } } /* if (0 != (menuitem->Flags & ITEMTEXT)) else ... */ curY += menuitem->Height; /* ** In case this menu becomes too high it will have more columns. */ if (curY > vi->vi_screen->Height) { ULONG width; width = EqualizeItems(equalizeitem, menuitem, amikeyimage, vi, GadToolsBase); equalizeitem = menuitem; curY = 0; curX += width + MENU_COLUMN_SPACING; menuitem->LeftEdge = curX; menuitem->TopEdge = curY; curY += menuitem->Height; numcolumns++; } /* ** Process the next menu item */ menuitem = menuitem->NextItem; } /* while (NULL != menuitem) */ EqualizeItems(equalizeitem, NULL, amikeyimage, vi, GadToolsBase); menu = (struct Menu *)GetTagData(GTMN_Menu, 0, taglist); if (menu && (menu->FirstItem == firstitem)) { /* Make sure the menu box is at least as large as the menu title, otherwise it looks ugly */ WORD menuwidth, minx, maxx, titlewidth, prevy = -1, col = 1; minx = 32767; maxx = -32768; for(menuitem = firstitem; menuitem; menuitem = menuitem->NextItem) { if (menuitem->LeftEdge < minx) minx = menuitem->LeftEdge; if (menuitem->LeftEdge + menuitem->Width - 1 > maxx) maxx = menuitem->LeftEdge + menuitem->Width - 1; } menuwidth = maxx - minx + 1; titlewidth = TextLength(&vi->vi_screen->RastPort, menu->MenuName, strlen(menu->MenuName)); if (titlewidth > menuwidth) { WORD extrawidth = (titlewidth - menuwidth + numcolumns / 2) / numcolumns; for(menuitem = firstitem; menuitem; menuitem = menuitem->NextItem) { struct MenuItem *subitem; if (menuitem->TopEdge < prevy) col++; prevy = menuitem->TopEdge; menuitem->LeftEdge += (col - 1) * extrawidth; menuitem->Width += extrawidth; if (menuitem->Flags & ITEMTEXT) { struct IntuiText *it = (struct IntuiText *)menuitem->ItemFill; if ((it = it->NextText)) { it->LeftEdge += extrawidth; } } else { struct Image *im = (struct Image *)menuitem->ItemFill; if (is_menubarlabelclass_image(im, GadToolsBase)) { im->Width += extrawidth; } } if ((subitem = menuitem->SubItem)) { while(subitem) { subitem->LeftEdge += extrawidth; subitem = subitem->NextItem; } } } /* for(menuitem = firstitem; menuitem; menuitem = menuitem->NextItem) */ } /* if (titlewidth > menuwidth) */ } /* if (menu && (menu->FirstItem == firstitem)) */ return TRUE; }
static ULONG EqualizeItems(struct MenuItem *firstitem, struct MenuItem *lastitem, struct Image *amikeyimage, struct VisualInfo *vi, struct GadToolsBase_intern * GadToolsBase) { struct MenuItem *item; struct TextExtent te; WORD minx = 0, maxwidth = 0, maxrightstuffwidth = 0; if (!firstitem) return 0; /* Calc. the max. width of item text/image (+ checkmark image) Calc. the min. item->LeftEdge */ for(item = firstitem; item && (item != lastitem); item = item->NextItem) { if (item->LeftEdge < minx) minx = item->LeftEdge; if (item->Width > maxwidth) maxwidth = item->Width; } /* Calc. the max. width of AmigaKey/CommandString/">>" */ FontExtent(vi->vi_dri->dri_Font, &te); for(item = firstitem; item && (item != lastitem); item = item->NextItem) { WORD width = 0; if (item->Flags & COMMSEQ) { width = te.te_Width; if (item->Flags & ITEMTEXT) { struct TextFont *font; struct IntuiText *it = (struct IntuiText *)item->ItemFill; if (it->ITextFont) { if ((font = OpenFont(it->ITextFont))) { struct TextExtent e; FontExtent(font, &e); width = e.te_Width; CloseFont(font); } } } width += amikeyimage->Width + AMIGAKEY_KEY_SPACING; } else if (item->Flags & ITEMTEXT) { struct IntuiText *it = (struct IntuiText *)item->ItemFill; struct IntuiText *it2; if ((it2 = it->NextText)) { it2->FrontPen = it->FrontPen; it2->BackPen = it->BackPen; it2->DrawMode = it->DrawMode; it2->TopEdge = it->TopEdge; /* save width also in it->LeftEdge. Will be used below to calc. x position */ width = it2->LeftEdge = MyIntuiTextLength(vi, it2, GadToolsBase); } } if (width > maxrightstuffwidth) maxrightstuffwidth = width; } /* for(item = firstitem; item; item = item->NextItem) */ /* Calc. x coordinate of command strings and ">>"'s and submenu pos. */ if (maxrightstuffwidth) { maxwidth += maxrightstuffwidth + TEXT_AMIGAKEY_SPACING; for(item = firstitem; item && (item != lastitem); item = item->NextItem) { struct MenuItem *subitem; if (item->Flags & ITEMTEXT) { struct IntuiText *it = (struct IntuiText *)item->ItemFill; if ((it = it->NextText)) { /* it->LeftEdge contains the pixel width. see above */ it->LeftEdge = minx + maxwidth - it->LeftEdge - ITEXT_EXTRA_RIGHT; } } for(subitem = item->SubItem; subitem; subitem = subitem->NextItem) { subitem->LeftEdge += (maxwidth - maxrightstuffwidth); } } } /* if (maxrightstuffwidth) */ /* Make all items have the same width and set also the width and the drawinfo of barlabel images */ for(item = firstitem; item && (item != lastitem); item = item->NextItem) { item->Width = maxwidth; if(!(item->Flags & ITEMTEXT)) { struct Image *im = (struct Image *)item->ItemFill; if (is_menubarlabelclass_image(im, GadToolsBase)) { struct TagItem image_tags [] = { {IA_Width , maxwidth - ITEXT_EXTRA_LEFT - ITEXT_EXTRA_RIGHT }, {SYSIA_DrawInfo , (IPTR)vi->vi_dri }, {TAG_DONE } }; SetAttrsA(im, image_tags); } } } return (ULONG)maxwidth; }
// Listview dispatcher ULONG LIBFUNC listview_dispatch( REG(a0, Class *cl), REG(a2, Object *obj), REG(a1, Msg msg)) { ListViewData *data=0; struct Gadget *gadget=0; ULONG retval=0; // Get gadget and data pointers if (obj) { gadget=(struct Gadget *)obj; data=INST_DATA(cl,obj); } // Look at method switch (msg->MethodID) { // Create a new instance case OM_NEW: // Create superclass instance if ((retval=DoSuperMethodA(cl,obj,msg))) { struct TagItem *tags,*tag; short a; struct Image *image; struct TextAttr *attr; // Get pointer to our gadget and instance data gadget=(struct Gadget *)retval; data=INST_DATA(cl,(APTR)retval); // Initialise data data->dims=*(struct IBox *)&gadget->LeftEdge; NewList(&data->boopsi_list); data->sel=-1; data->last_selection=-1; // Initialise mapping tags data->scroll_map[0].ti_Tag=PGA_Top; data->scroll_map[0].ti_Data=DLV_Top; data->scroll_map[1].ti_Tag=TAG_END; data->arrow_up_map[0].ti_Tag=GA_ID; data->arrow_up_map[0].ti_Data=DLV_ScrollUp; data->arrow_up_map[1].ti_Tag=TAG_END; data->arrow_down_map[0].ti_Tag=GA_ID; data->arrow_down_map[0].ti_Data=DLV_ScrollDown; data->arrow_down_map[1].ti_Tag=TAG_END; // Get taglist tags=((struct opSet *)msg)->ops_AttrList; // Get width of scroller data->scroller_width=GetTagData(DLV_ScrollWidth,16,tags); // Flags if (FindTagItem(DLV_ShowSelected,tags)) data->flags|=LVF_SHOW_SELECTED; if (GetTagData(DLV_ThinBorder,0,tags)) data->flags|=LVF_THIN_BORDER; if (GetTagData(DLV_MultiSelect,0,tags)) data->flags|=LVF_MULTI_SELECT; else if (GetTagData(DLV_Check,0,tags)) data->flags|=LVF_SELECTED_CHECK; else if ((a=GetTagData(DLV_ShowChecks,0,tags))) { data->flags|=LVF_SHOW_CHECKS; if (a==2) data->flags|=LVF_NO_HIGHLIGHT; } if (GetTagData(DLV_Highlight,0,tags)) data->flags|=LVF_SELECTED_HIGH; if (GetTagData(DLV_ReadOnly,0,tags)) data->flags|=LVF_READ_ONLY; if (GetTagData(DLV_NoScroller,0,tags)) { data->flags|=LVF_NO_SCROLLER; data->scroller_width=0; } else if (GetTagData(DLV_ScrollLeft,0,tags)) data->flags|=LVF_SCROLLER_LEFT; if (GetTagData(DLV_TopJustify,0,tags)) data->flags|=LVF_TOP_JUSTIFY; if (GetTagData(DLV_RightJustify,0,tags)) data->flags|=LVF_RIGHT_JUSTIFY; if ((a=GetTagData(DLV_DragNotify,0,tags))) { data->flags|=LVF_DRAG_NOTIFY; if (a==2) data->flags|=LVF_NO_VERT_SCROLL; } data->layout_flags=GetTagData(DLV_Flags,PLACETEXT_ABOVE,tags); if (GetTagData(DLV_ShowFilenames,0,tags)) data->flags|=LVF_SHOW_FILENAMES; if (GetTagData(DLV_ShowSeparators,0,tags)) data->flags|=LVF_SHOW_SEPARATORS; // Get title if ((tag=FindTagItem(GA_Text,tags))) { char *ptr; short pos=0; // Get pointer to title if ((ptr=(char *)tag->ti_Data)) { data->title_uscore=-1; // Copy title string, look for underscore while (*ptr && pos<78) { // Underscore? if (*ptr=='_') { // Remember position, skip over it data->title_uscore=pos; } // Otherwise, store else data->title[pos++]=*ptr; ++ptr; } data->title[pos]=0; } } // Get font to use if ((attr=(struct TextAttr *)GetTagData(GTCustom_TextAttr,0,tags))) { if ((data->list_font=OpenFont(attr))) data->flags|=LVF_GOT_FONT; } if (!data->list_font) data->list_font=((struct GfxBase *)GfxBase)->DefaultFont; // Arrow height data->arrow_height=data->list_font->tf_YSize-2; if (data->arrow_height<10) data->arrow_height=10; // Fix dimensions listview_get_dims(cl,data); data->text_height=data->list_font->tf_YSize; // Need check mark? if (data->flags&(LVF_MULTI_SELECT|LVF_SHOW_CHECKS) || (data->flags&(LVF_SHOW_SELECTED|LVF_SELECTED_CHECK))==(LVF_SHOW_SELECTED|LVF_SELECTED_CHECK)) { // Create check image if ((data->check=(struct Image *)NewObject( 0,"dopusiclass", DIA_Type,IM_CHECK, IA_Width,13, IA_Height,data->text_height-1, TAG_END))) { // Add to boopsi list DoMethod((Object *)data->check,OM_ADDTAIL,&data->boopsi_list); } data->text_offset=23; } else data->text_offset=2; // Scroller needed? if (!(data->flags&LVF_NO_SCROLLER)) { // Create scroller if ((data->scroller=(struct Gadget *)NewObject( 0,"propgclass", GA_Previous,gadget, GA_ID,LVGID_SCROLLER, GA_Left,(data->flags&LVF_SCROLLER_LEFT)?data->dims.Left+4:data->dims.Left+data->dims.Width-data->scroller_width+4, GA_Top,data->dims.Top+2, GA_Width,data->scroller_width-8, GA_Height,data->dims.Height-4-(data->arrow_height<<1), GA_Disabled,(gadget->Flags&GFLG_DISABLED)?TRUE:FALSE, PGA_Freedom,FREEVERT, PGA_NewLook, TRUE, PGA_Borderless,TRUE, PGA_Visible,1, PGA_Total,1, ICA_TARGET,gadget, ICA_MAP,data->scroll_map, TAG_END))) { // Add to boopsi list DoMethod((Object *)data->scroller,OM_ADDTAIL,&data->boopsi_list); } // Create up arrow image if ((image=(struct Image *)NewObject( 0,"dopusiclass", IA_Width,data->scroller_dims.Width, IA_Height,data->arrow_height, DIA_Type,IM_ARROW_UP, DIA_ThinBorders,(data->flags&LVF_THIN_BORDER)?TRUE:FALSE, TAG_END))) { // Add to boopsi list DoMethod((Object *)image,OM_ADDTAIL,&data->boopsi_list); } // Create up arrow button if ((data->arrows[0]=(struct Gadget *)NewObject( 0,"buttongclass", GA_ID,LVGID_ARROW, GA_Previous,data->scroller, GA_Left,data->scroller_dims.Left, GA_Top,data->scroller_dims.Top+data->scroller_dims.Height, GA_Width,data->scroller_dims.Width, GA_Height,data->arrow_height, GA_Image,image, GA_Disabled,(gadget->Flags&GFLG_DISABLED)?TRUE:FALSE, ICA_TARGET,gadget, ICA_MAP,data->arrow_up_map, TAG_END))) { // Add to boopsi list DoMethod((Object *)data->arrows[0],OM_ADDTAIL,&data->boopsi_list); } // Create down arrow image if ((image=(struct Image *)NewObject( 0,"dopusiclass", IA_Width,data->scroller_dims.Width, IA_Height,data->arrow_height, DIA_Type,IM_ARROW_DOWN, DIA_ThinBorders,(data->flags&LVF_THIN_BORDER)?TRUE:FALSE, TAG_END))) { // Add to boopsi list DoMethod((Object *)image,OM_ADDTAIL,&data->boopsi_list); } // Create down arrow button if ((data->arrows[1]=(struct Gadget *)NewObject( 0,"buttongclass", GA_ID,LVGID_ARROW, GA_Previous,data->arrows[0], GA_Left,data->scroller_dims.Left, GA_Top,data->scroller_dims.Top+data->scroller_dims.Height+data->arrow_height, GA_Width,data->scroller_dims.Width, GA_Height,data->arrow_height, GA_Image,image, GA_Disabled,(gadget->Flags&GFLG_DISABLED)?TRUE:FALSE, ICA_TARGET,gadget, ICA_MAP,data->arrow_down_map, TAG_END))) { // Add to boopsi list DoMethod((Object *)data->arrows[1],OM_ADDTAIL,&data->boopsi_list); } } } else break; // Fall through to OM_SET // Update/Set case OM_UPDATE: case OM_SET: { struct TagItem *tag,*tags; unsigned short old; struct Node *node; short item; short redraw=0; // Get taglist tags=((struct opSet *)msg)->ops_AttrList; // Make visible? if ((tag=FindTagItem(DLV_MakeVisible,tags))) { short scroll; // Remember old top old=data->top; // Get scroll amount scroll=tag->ti_Data-old; // Need to scroll? if (scroll<0 || scroll>=data->lines) { // Get scroll amount if (scroll>=data->lines) scroll-=data->lines-1; // Get new top data->top+=scroll; // Bounds check if (data->top>data->count-data->lines) data->top=data->count-data->lines; if (data->top<0) data->top=0; // Redraw? if (old!=data->top) { data->last_sel=-1; redraw=2; } } } // New top? else if ((tag=FindTagItem(DLV_Top,tags))) { // Remember old top old=data->top; // Get new top data->top=tag->ti_Data; // Bounds check if (data->top>data->count-data->lines) data->top=data->count-data->lines; if (data->top<0) data->top=0; // Redraw? if (old!=data->top) { data->last_sel=-1; redraw=2; } } // Scroll up else if ((tag=FindTagItem(DLV_ScrollUp,tags))) { // Is this the gadgetup? if (msg->MethodID==OM_UPDATE && !(((struct opUpdate *)msg)->opu_Flags&OPUF_INTERIM)) { // Clear scroll count data->scroll_count=0; } // Or is this the second/third scroll (first/second intuitick)? else if (msg->MethodID==OM_UPDATE && (data->scroll_count==1 || data->scroll_count==2)) { // Throw this away ++data->scroll_count; } // Otherwise, check it's valid else if (tag->ti_Data!=(ULONG)-LVGID_ARROW) { // Bounds check if (data->top>0) { --data->top; data->last_sel=-1; redraw=2; } // Increment scroll count if necessary if (msg->MethodID==OM_UPDATE) ++data->scroll_count; } } // Scroll down else if ((tag=FindTagItem(DLV_ScrollDown,tags))) { // Is this the gadgetup? if (msg->MethodID==OM_UPDATE && !(((struct opUpdate *)msg)->opu_Flags&OPUF_INTERIM)) { // Clear scroll count data->scroll_count=0; } // Or is this the second/third scroll (first/second intuitick)? else if (msg->MethodID==OM_UPDATE && (data->scroll_count==1 || data->scroll_count==2)) { // Throw this away ++data->scroll_count; } // Otherwise, check it's valid else if (tag->ti_Data!=(ULONG)-LVGID_ARROW) { // Bounds check if (data->top<data->count-data->lines) { ++data->top; data->last_sel=-1; redraw=2; } // Increment scroll count if necessary if (msg->MethodID==OM_UPDATE) ++data->scroll_count; } } // New labels if ((tag=FindTagItem(DLV_Labels,tags))) { // clear top item data->top_item=0; // Store new label pointer data->labels=(struct List *)tag->ti_Data; // Detached list? if (data->labels==(struct List *)~0) data->flags|=LVF_DETACHED; // No list else if (data->labels==0) { // Clear detach flag data->count=0; data->flags&=~LVF_DETACHED; redraw=1; } // Valid list else { // Count items for (data->count=0,node=data->labels->lh_Head; node->ln_Succ; data->count++,node=node->ln_Succ); // Bounds check top if (data->top+data->lines>data->count) data->top=data->count-data->lines; if (data->top<0) data->top=0; // Check selection for out-of-bounds if (data->sel>data->count-1) data->sel=-1; // Clear detach flag data->flags&=~LVF_DETACHED; redraw=1; } } // Selected if ((tag=FindTagItem(DLV_Selected,tags)) || (tag=FindTagItem(DLV_SelectPrevious,tags)) || (tag=FindTagItem(DLV_SelectNext,tags)) || (tag=FindTagItem(DLV_PageUp,tags)) || (tag=FindTagItem(DLV_PageDown,tags)) || (tag=FindTagItem(DLV_Home,tags)) || (tag=FindTagItem(DLV_End,tags))) { // Store old old=data->sel; // Get new selected if (tag->ti_Tag==DLV_Selected) { data->sel=tag->ti_Data; } else if (tag->ti_Tag==DLV_SelectPrevious) { if (data->sel>0) --data->sel; } else if (tag->ti_Tag==DLV_SelectNext) { ++data->sel; } else if (tag->ti_Tag==DLV_PageUp) { if (data->sel==data->top) data->sel-=data->lines-1; else data->sel=data->top; if (data->sel<0) data->sel=0; } else if (tag->ti_Tag==DLV_PageDown) { if (data->sel==data->top+data->lines-1) data->sel+=data->lines-1; else data->sel=data->top+data->lines-1; } else if (tag->ti_Tag==DLV_Home) { data->sel=0; } else if (tag->ti_Tag==DLV_End) { data->sel=data->count-1; } // Bounds check if (data->sel>data->count-1) data->sel=data->count-1; if (data->sel<0) data->sel=-1; // Changed? if (data->sel!=old && !(gadget->Flags&GFLG_DISABLED)) { // Save selection if (!redraw) { data->last_sel=data->last_selection; redraw=2; } data->last_selection=data->sel; // Send notify DoMethod(obj,OM_NOTIFY,0,((struct opSet *)msg)->ops_GInfo,0); } } // Disabled (set only) if (msg->MethodID==OM_SET && (tag=FindTagItem(GA_Disabled,tags))) { // Different to current state? if ((tag->ti_Data && !(gadget->Flags&GFLG_DISABLED)) || (!tag->ti_Data && gadget->Flags&GFLG_DISABLED)) { struct TagItem distags[2]; short a; // Fill out disable tags distags[0].ti_Tag=GA_Disabled; distags[0].ti_Data=tag->ti_Data; distags[1].ti_Tag=TAG_DONE; // Set state of slider if (data->scroller) { DoMethod( (Object *)data->scroller, OM_SET, distags, ((struct opSet *)msg)->ops_GInfo); // And arrows for (a=0;a<2;a++) DoMethod( (Object *)data->arrows[a], OM_SET, distags, ((struct opSet *)msg)->ops_GInfo); // Set flag to say disable state changed if (!tag->ti_Data) data->flags|=LVF_DISABLE_CHANGE; } // Change disable state and redraw gadget->Flags^=GFLG_DISABLED; redraw=1; } } // Get top item if (!data->labels) data->top_item=0; else if (!(data->flags&LVF_DETACHED) && data->labels) { for (node=data->labels->lh_Head,item=0; node->ln_Succ && item<data->top; node=node->ln_Succ,item++); data->top_item=node; } // Do we need to redraw the list? if (msg->MethodID==OM_SET || msg->MethodID==OM_UPDATE) { if (redraw && !(data->flags&LVF_DETACHED)) { struct RastPort *rp; // Get rastport if ((rp=ObtainGIRPort(((struct opSet *)msg)->ops_GInfo))) { // Send redraw DoMethod( obj, GM_RENDER, ((struct opSet *)msg)->ops_GInfo, rp, (redraw==2)?GREDRAW_UPDATE:GREDRAW_REDRAW); ReleaseGIRPort(rp); } } } } break; // Get an attribute case OM_GET: { struct opGet *get; // Get get message get=(struct opGet *)msg; // Default to ok retval=1; // Look at attribute switch (get->opg_AttrID) { // Selected case DLV_Selected: *get->opg_Storage=(ULONG)data->last_selection; break; // Top case DLV_Top: *get->opg_Storage=(ULONG)data->top; break; // Lines case DLV_Lines: *get->opg_Storage=(ULONG)data->lines; break; // Labels case DLV_Labels: *get->opg_Storage=(ULONG)data->labels; break; // Get line from coordinates case DLV_GetLine: { unsigned short x,y; struct gpInput fake; // Get coordinates x=((*get->opg_Storage)>>16)&0xffff; y=(*get->opg_Storage)&0xffff; // Fake gpInput fake.gpi_Mouse.X=x-gadget->LeftEdge; fake.gpi_Mouse.Y=y-gadget->TopEdge; // Get selection *get->opg_Storage=(ULONG)listview_get_sel(cl,gadget,data,&fake,0); } break; // Draw a line from the listview case DLV_DrawLine: { ListViewDraw *draw=(ListViewDraw *)*get->opg_Storage; // Draw line listview_draw_item( cl, gadget, draw->rp, draw->drawinfo, data, draw->node, draw->line, &draw->box); } break; // Other default: retval=DoSuperMethodA(cl,obj,msg); break; } } break; // Kill an instance case OM_DISPOSE: { APTR object_ptr; Object *object; // Free BOOPSI objects object_ptr=data->boopsi_list.lh_Head; while ((object=NextObject((APTR)&object_ptr))) DisposeObject(object); // Free font if (data->flags&LVF_GOT_FONT) CloseFont(data->list_font); retval=DoSuperMethodA(cl,obj,msg); } break; // Render gadget case GM_RENDER: // Cache DrawInfo data->draw_info=((struct gpRender *)msg)->gpr_GInfo->gi_DrInfo; // If a full redraw, clear double-click time if (((struct gpRender *)msg)->gpr_Redraw==GREDRAW_REDRAW) data->seconds=0; // Show gadget listview_render(cl,gadget,data,(struct gpRender *)msg); break; // Hit test case GM_HITTEST: { struct gpHitTest *test; // Get test pointer test=(struct gpHitTest *)msg; // See if we're hit if (test->gpht_Mouse.X>=data->text_dims.Left-gadget->LeftEdge && test->gpht_Mouse.Y>=data->text_dims.Top-gadget->TopEdge && test->gpht_Mouse.X<data->text_dims.Left+data->text_dims.Width-gadget->LeftEdge && test->gpht_Mouse.Y<data->text_dims.Top+data->text_dims.Height-gadget->TopEdge) { retval=GMR_GADGETHIT; } } break; // Notify case OM_NOTIFY: // Drag notify? if (data->flags&LVF_DRAG_FLAG) { // Fill out tags data->notify_tags[0].ti_Tag=DLV_DragNotify; data->notify_tags[0].ti_Data=data->drag_sel; data->notify_tags[1].ti_Tag=GA_ID; data->notify_tags[1].ti_Data=gadget->GadgetID; data->notify_tags[2].ti_Tag=GA_Left; data->notify_tags[2].ti_Data=data->text_dims.Left; data->notify_tags[3].ti_Tag=GA_Top; data->notify_tags[3].ti_Data=data->text_dims.Top+ UMult32(data->drag_sel-data->top,data->text_height); data->notify_tags[4].ti_Tag=GA_Width; data->notify_tags[4].ti_Data=data->text_dims.Width; data->notify_tags[5].ti_Tag=GA_Height; data->notify_tags[5].ti_Data=data->text_height; data->notify_tags[6].ti_Tag=GA_RelRight; data->notify_tags[6].ti_Data=data->drag_x_position; data->notify_tags[7].ti_Tag=GA_RelBottom; data->notify_tags[7].ti_Data=data->drag_y_position; data->notify_tags[8].ti_Tag=DLV_Top; data->notify_tags[8].ti_Data=data->top; data->notify_tags[9].ti_Tag=DLV_Object; data->notify_tags[9].ti_Data=(ULONG)gadget; data->notify_tags[10].ti_Tag=TAG_END; // Clear flag data->flags&=~LVF_DRAG_FLAG; } // Otherwise normal notify else { ULONG seconds,micros; // Fill out tags data->notify_tags[0].ti_Tag=DLV_Selected; data->notify_tags[0].ti_Data=data->last_selection; data->notify_tags[1].ti_Tag=GA_ID; data->notify_tags[1].ti_Data=gadget->GadgetID; data->notify_tags[2].ti_Tag=TAG_END; // Get current time CurrentTime(&seconds,µs); // Double-click? if (data->click_sel==data->last_selection && DoubleClick(data->seconds,data->micros,seconds,micros)) { // Set double-click flag data->notify_tags[2].ti_Tag=DLV_DoubleClick; data->notify_tags[2].ti_Data=TRUE; data->notify_tags[3].ti_Tag=TAG_END; // Clear double-click data->seconds=0; } // Otherwise else { // Remember double-click data->seconds=seconds; data->micros=micros; data->click_sel=data->last_selection; } } // Send message DoSuperMethod(cl,obj,OM_NOTIFY,data->notify_tags,((struct opUpdate *)msg)->opu_GInfo,0); break; // Go (in)active/Handle input case GM_GOACTIVE: case GM_GOINACTIVE: case GM_HANDLEINPUT: { struct gpInput *input; short redraw=0; // Get input pointer input=(struct gpInput *)msg; // Go active? if (input->MethodID==GM_GOACTIVE) { // Default is not to activate retval=GMR_NOREUSE; // Ok to go active? if (!(gadget->Flags&GFLG_DISABLED) && input->gpi_IEvent) { // Left button down and valid list? if (input->gpi_IEvent->ie_Code==SELECTDOWN && data->labels && !(data->flags&(LVF_READ_ONLY|LVF_DETACHED))) { short sel; // Get selection if ((sel=listview_get_sel(cl,gadget,data,input,0))>-1) { // Ok to activate retval=GMR_MEACTIVE; // Store current top data->last_top=data->top; // Remember x and y click-offset data->drag_x_position=input->gpi_Mouse.X- (data->text_dims.Left-data->dims.Left); data->drag_y_position=input->gpi_Mouse.Y- (data->text_dims.Top-data->dims.Top)- UMult32(sel-data->top,data->text_height); // Change? if (data->sel!=sel || !(data->flags&LVF_SHOW_SELECTED) || (data->flags&LVF_SELECTED_CHECK)) { // New selection data->last_sel=data->last_selection; data->sel=sel; redraw=1; } // Set selected flag gadget->Flags|=GFLG_SELECTED; } } } } // Go inactive? else if (msg->MethodID==GM_GOINACTIVE) { // Clear selected flag gadget->Flags&=~GFLG_SELECTED; // If we're showing selection with checks, we need to redraw last selection if ((data->flags&(LVF_SHOW_SELECTED|LVF_SELECTED_CHECK))==(LVF_SHOW_SELECTED|LVF_SELECTED_CHECK)) data->last_sel=data->last_selection; redraw=1; // Save this selection data->last_selection=data->sel; // Send notify DoMethod(obj,OM_NOTIFY,0,((struct gpInput *)msg)->gpi_GInfo,0); // Clear cancel flag data->flags&=~LVF_CANCEL; } // Handle input else { // Default return value retval=GMR_MEACTIVE; // Is it a mouse event? if (input->gpi_IEvent->ie_Class==IECLASS_RAWMOUSE) { // Look at mouse code switch (input->gpi_IEvent->ie_Code) { // Left button up case SELECTUP: { // Set return code *input->gpi_Termination=data->sel; // Gadget processing finished retval=GMR_NOREUSE|GMR_VERIFY; data->flags|=LVF_CANCEL; // Multi-selection? if (data->flags&LVF_MULTI_SELECT) { struct Node *node; short count; // Get this node for (node=data->labels->lh_Head,count=0; node->ln_Succ && count<data->sel; node=node->ln_Succ,count++); // Did we get it? if (node && node->ln_Succ) { // Save old selection data->last_sel=data->sel; // Toggle selection node->lve_Flags^=LVEF_SELECTED; redraw=1; } } } break; // No button; mouse moved case IECODE_NOBUTTON: { short sel; // Is mouse outside of lister? if (input->gpi_Mouse.X<0 || input->gpi_Mouse.X>=data->list_dims.Width) { // Drag notify? if (data->flags&LVF_DRAG_NOTIFY) { // Valid selection? if (data->sel>-1) { // Notify drag data->flags|=LVF_DRAG_FLAG; data->drag_sel=data->sel; // Will fall through to MENUDOWN (if NO_VERT_SCROLL) if (!(data->flags&LVF_NO_VERT_SCROLL)) { retval=GMR_NOREUSE; data->flags|=LVF_CANCEL; break; } } else break; } else break; } // Get selection else if ((sel=listview_get_sel(cl,gadget,data,input,1))>-1 || (sel==-1 && (data->flags&LVF_NO_VERT_SCROLL))) { // Change? if (data->sel!=sel || sel==-1) { // Clear double-click data->seconds=0; // No vertical scroll? if (data->flags&LVF_NO_VERT_SCROLL) { // Drag notify? if (data->flags&LVF_DRAG_NOTIFY) { // Notify drag data->flags|=LVF_DRAG_FLAG; data->drag_sel=data->sel; // Will fall through to MENUDOWN } else break; } // Otherwise else { // Save old selection data->last_sel=data->sel; // New selection data->sel=sel; redraw=1; break; } } else break; } else break; } // Right button does cancel case MENUDOWN: { // Gadget processing finished retval=GMR_NOREUSE; data->flags|=LVF_CANCEL; // Show selected? if (data->flags&LVF_SHOW_SELECTED) { // Restore last selection data->last_sel=data->sel; data->sel=data->last_selection; // Does top need to change? if (data->top!=data->last_top) { short item; data->top=data->last_top; data->last_sel=-1; for (data->top_item=data->labels->lh_Head,item=0; data->top_item->ln_Succ && item<data->top; data->top_item=data->top_item->ln_Succ,item++); } redraw=1; } } break; } } // Or a timer event else if (input->gpi_IEvent->ie_Class==IECLASS_TIMER) { short sel; // Get selection if ((sel=listview_get_sel(cl,gadget,data,input,2))>-1) { // Change? if (data->sel!=sel) { // Save old selection data->last_sel=data->sel; // New selection data->sel=sel; // Do we have to scroll? if (sel<data->top) { if (data->top>0) { // Scroll up --data->top; data->top_item=data->top_item->ln_Pred; // Redraw the list data->last_sel=-1; redraw=1; } } else if (sel>=data->top+data->lines) { if (data->top+data->lines<data->count) { // Scroll down ++data->top; data->top_item=data->top_item->ln_Succ; // Redraw the list data->last_sel=-1; redraw=1; } } else redraw=1; } } } } // Redraw needed? if (redraw) { struct RastPort *rp; // Get rastport if ((rp=ObtainGIRPort(input->gpi_GInfo))) { // Send redraw DoMethod(obj,GM_RENDER,input->gpi_GInfo,rp,GREDRAW_UPDATE); ReleaseGIRPort(rp); } } } break; // Resize case GM_RESIZE: // Handle the resize listview_resize(cl,gadget,data,(struct gpResize *)msg); break; // Unknown method default: retval=DoSuperMethodA(cl,obj,msg); break; } return retval; }
STATIC IPTR _OM_SET(Class *cl, Object *o,struct opSet *msg) { IPTR retval = (IPTR)0; const struct TagItem *tag, *tstate; struct LVData *data; EnterFunc(bug("ListView::OM_SET\n")); data = INST_DATA(cl, o); tstate = msg->ops_AttrList; /* Set to 1 to signal visual changes */ while ((tag = NextTagItem(&tstate)) != NULL) { switch (tag->ti_Tag) { case AROSA_Listview_DisplayHook: data->lvd_DisplayHook = (struct Hook *)tag->ti_Data; retval = 1UL; break; case AROSA_Listview_FrontPen: data->lvd_FrontPen = (UBYTE)tag->ti_Data; retval = 1UL; break; case AROSA_Listview_BackPen: data->lvd_BackPen = (UBYTE)tag->ti_Data; retval = 1UL; break; case AROSA_Listview_Visible: case AROSA_Listview_Total: { struct TagItem tags[] = { {tag->ti_Tag, tag->ti_Data}, {TAG_END} }; NotifyAttrs(cl, o, msg, tags); } break; case AROSA_Listview_List: { ULONG numentries; struct TagItem tags[] = { {AROSA_Listview_First, 0}, {AROSA_Listview_Total, 0}, {TAG_END} }; data->lvd_List = (Object *)tag->ti_Data; GetAttr(AROSA_List_Entries, data->lvd_List, (IPTR *)&numentries); SetAttrs(data->lvd_List, AROSA_List_Active, AROSV_List_Active_None, TAG_END); tags[1].ti_Data = numentries; DoMethod(o, OM_SET, (IPTR) tags, (IPTR) msg->ops_GInfo); retval = 1UL; } break; case AROSA_Listview_HorSpacing: data->lvd_HorSpacing = (UBYTE)tag->ti_Data; retval = 1UL; break; case AROSA_Listview_VertSpacing: data->lvd_VertSpacing = (UBYTE)tag->ti_Data; ReCalcEntryHeight(data); retval = 1UL; break; case AROSA_Listview_Format: { struct ColumnAttrs *colattrs = data->lvd_ColAttrs; ULONG colattrsz = UB(&colattrs[data->lvd_MaxColumns]) - UB(&colattrs[0]); memset(colattrs, 0, colattrsz); ParseFormatString((STRPTR)tag->ti_Data, data); retval = 1UL; } break; case AROSA_Listview_First: { struct TagItem tags[] = { {AROSA_Listview_First, tag->ti_Data}, {TAG_END} }; LONG old = data->lvd_First; #if DEBUG if (msg->MethodID == OM_SET) { D(bug("_First OM_SET\n")); } else { D(bug("_First OM_UPDATEd, lvd_NC=%d\n", data->lvd_NotifyCount)); } #endif retval = 1UL; data->lvd_First = (LONG)tag->ti_Data; if ( ( msg->MethodID == OM_UPDATE ) && ( old != data->lvd_First )) { struct RastPort *rp; WORD steps; UWORD visible, abs_steps; struct IBox box; steps = tag->ti_Data - old; abs_steps = steps < 0 ? -steps : steps; GetGadgetIBox(o, msg->ops_GInfo, &box); visible = NumVisible(&box, data->lvd_EntryHeight); if (abs_steps < visible >> 1) { if ((rp = ObtainGIRPort(msg->ops_GInfo)) != NULL) { LONG dy; /* We make the assumption that the listview ** is alvays 'full'. If it isn't, the ** Scroll gadget won't be scrollable, and ** we won't receive any OM_UPDATEs. */ dy = steps * data->lvd_EntryHeight; ScrollRaster(rp, 0, dy, box.Left + LV_BORDERWIDTH_X, box.Top + LV_BORDERWIDTH_Y, box.Left + box.Width - 1 - LV_BORDERWIDTH_X, box.Top + LV_BORDERWIDTH_Y + visible * data->lvd_EntryHeight); data->lvd_DamageOffset = ((steps > 0) ? visible - abs_steps : 0); data->lvd_NumDamaged = abs_steps; DoMethod(o, GM_RENDER, (IPTR) msg->ops_GInfo, (IPTR) rp, GREDRAW_UPDATE); ReleaseGIRPort(rp); retval = 0UL; } /* if (ObtainGIRPort succeed) */ } /* if (at most half the visible entries scrolled out) */ } /* if (msg is of type OM_UPDATE) */ /* Notify change */ NotifyAttrs(cl, o, msg, tags); } break; case AROSA_Listview_RenderHook: data->lvd_RenderHook = (struct Hook *)data->lvd_RenderHook; retval = 1UL; break; case AROSA_Listview_MultiSelect: SETFLAG(data->lvd_Flags, tag->ti_Data, LVFLG_MULTISELECT); break; case GA_TextAttr: { struct TextFont *tf; tf = OpenFont((struct TextAttr *)tag->ti_Data); if (tf) { if (data->lvd_Font) { CloseFont(data->lvd_Font); } data->lvd_Font = tf; } ReCalcEntryHeight(data); } break; default: break; } /* switch (tag->ti_Tag) */ } /* while (more tags to iterate) */ ReturnPtr("ListView::OM_SET", IPTR, retval); }
IPTR AROSListview__OM_NEW(Class *cl, Object *o, struct opSet *msg) { struct LVData *data; struct ColumnAttrs *colattrs; STRPTR *dharray; ULONG colattrsz; struct opSet ops, *p_ops = &ops; struct TagItem tags[] = { {GA_RelSpecial, TRUE}, {TAG_MORE, 0} }; ops.MethodID = OM_NEW; ops.ops_AttrList = &tags[0]; ops.ops_GInfo = NULL; tags[1].ti_Data = (IPTR)msg->ops_AttrList; o = (Object *)DoSuperMethodA(cl, o, (Msg)p_ops); if(!o) return (IPTR) NULL; D(bug("lv: obj created\n")); data = INST_DATA(cl, o); memset(data, 0, sizeof (struct LVData)); data->lvd_MaxColumns = GetTagData(AROSA_Listview_MaxColumns, 0, msg->ops_AttrList); if (!data->lvd_MaxColumns) goto failure; D(bug("Maxcolumns found: %d\n", data->lvd_MaxColumns)); /* Allocate mem for storing info parsed from Listview_Format. Do this * before listview_set() call, because it needs this for parsing the * format string. */ colattrsz = data->lvd_MaxColumns * sizeof (struct ColumnAttrs); colattrs = AllocVec(colattrsz, MEMF_ANY|MEMF_CLEAR); if (!colattrs) goto failure; data->lvd_ColAttrs = colattrs; D(bug("Colattrs allocated\n")); /* Only view first column */ data->lvd_ViewedColumns = 1; colattrs[0].ca_DHIndex = 0; /* Alloc mem for array to pass to _Listview_DisplayHook */ dharray = AllocVec(data->lvd_MaxColumns * sizeof (STRPTR), MEMF_ANY); if (!dharray) goto failure; data->lvd_DHArray = dharray; D(bug("disphookarray allocated\n")); /* Set some defaults */ data->lvd_HorSpacing = LV_DEFAULTHORSPACING; data->lvd_VertSpacing = LV_DEFAULTVERTSPACING; data->lvd_FrontPen = TEXTPEN; data->lvd_BackPen = BACKGROUNDPEN; /* Handle our special tags - overrides defaults */ _OM_SET(cl, o, msg); /* If not font has been set, use our own. */ if (!data->lvd_Font) { struct TextAttr tattr; struct TextFont *tf = GfxBase->DefaultFont; memset(&tattr, 0, sizeof (struct TextAttr)); tattr.ta_Name = tf->tf_Message.mn_Node.ln_Name; tattr.ta_YSize = tf->tf_YSize; tattr.ta_Style = tf->tf_Style; tattr.ta_Flags = tf->tf_Flags; if ((data->lvd_Font = OpenFont(&tattr)) == NULL) goto failure; ReCalcEntryHeight(data); } return ((IPTR)o); failure: CoerceMethod(cl, o, OM_DISPOSE); return (IPTR) NULL; }
main() { unsigned char str[256], *pp; int i; struct TextAttr ta = { "topaz.font", 8, FS_NORMAL, FPF_ROMFONT }; struct RastPort rp; struct BitMap bm = { 256, /* bytes per row */ 8, /* rows */ 0, /* flags */ 1, /* depth */ 0, /* pad */ 0 }; /* planes */ struct TextFont *tf; InitRastPort (& rp); rp.BitMap = &bm; bm.Planes[0] = pp = AllocRaster (256 * 8, 8); if (!pp) { fprintf (stderr, "Can't allocate raster!\n"); exit (1); } bzero (pp, 256 * 8); tf = OpenFont (& ta); if (! tf) { fprintf (stderr, "can't open topaz font.\n"); exit (1); } SetFont (&rp, tf); /* initialize string to be printed */ for (i = 32; i < 256; i++) str[i - 32] = i; Move (&rp, 0, 6); Text (&rp, str, 256 - 32); { int bin = open ("bitmap", 1); if (bin >= 0) { write (bin, pp, 256*8); close (bin); } } /* dump them.. */ printf ("/* generated automatically by dumpfont.c. *DONT* distribute\n"); printf (" this file, it contains information Copyright by Commodore!\n"); printf ("\n"); printf (" This is the (new) topaz80 system font: */\n\n"); printf ("unsigned char kernel_font_width = 8;\n"); printf ("unsigned char kernel_font_height = 8;\n"); printf ("unsigned char kernel_font_lo = 32;\n"); printf ("unsigned char kernel_font_hi = 255;\n\n"); printf ("unsigned char kernel_cursor[] = {\n"); printf (" 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };\n\n"); printf ("unsigned char kernel_font[] = {\n"); for (i = 0; i < 256 - 32; i++) { printf ("/* %c */ ", i + 32); printf ("0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n", pp[i+0*256], pp[i+1*256], pp[i+2*256], pp[i+3*256], pp[i+4*256], pp[i+5*256], pp[i+6*256], pp[i+7*256]); } printf ("};\n"); CloseFont (tf); FreeRaster (pp, 256 * 8, 8); }
IPTR GTText__OM_NEW(Class * cl, Object * o, struct opSet *msg) { EnterFunc(bug("Text::New()\n")); o = (Object *) DoSuperMethodA(cl, o, (Msg)msg); if (o) { struct TextData *data = INST_DATA(cl, o); struct TextAttr *tattr, def_tattr; /* Set some defaults */ data->format = "%ld"; data->flags = 0; data->frontpen = TEXTPEN; data->backpen = BACKGROUNDPEN; data->toprint = (IPTR) NULL; data->font = NULL; data->maxnumberlength = 0; /* This means "no limit" */ data->dispfunc = (APTR)GetTagData(GTA_Text_DispFunc, (IPTR) NULL, msg->ops_AttrList); data->labelplace = GetTagData(GA_LabelPlace, GV_LabelPlace_Left, msg->ops_AttrList); /* Open font to use for gadget */ /* We will *ALWAYS* have a valid DrawInfo struct */ data->dri = (struct DrawInfo *)GetTagData(GA_DrawInfo, (IPTR) NULL, msg->ops_AttrList); def_tattr.ta_Name = data->dri->dri_Font->tf_Message.mn_Node.ln_Name; def_tattr.ta_YSize = data->dri->dri_Font->tf_YSize; def_tattr.ta_Style = 0; def_tattr.ta_Flags = 0; tattr = (struct TextAttr *)GetTagData(GA_TextAttr, (IPTR)&def_tattr, msg->ops_AttrList); data->font = OpenFont(tattr); if (!data->font) goto error; if (GetTagData(GTTX_CopyText, (IPTR)FALSE, msg->ops_AttrList)) { STRPTR text; D(bug("Got GTTX_CopyText\n")); text = (STRPTR)GetTagData(GTTX_Text, (IPTR)"Text MUST be passed with OM_NEW", msg->ops_AttrList); if (text) { D(bug("Text: %s\n", text)); /* Allocate copy buffer for the text */ data->toprint = (IPTR)AllocVec(strlen(text) + 1, MEMF_ANY); if (data->toprint) { data->flags |= TEXTF_COPYTEXT; D(bug("Copying text\n")); strcpy((STRPTR)data->toprint, text); } else { goto error; } } else { /* If text==NULL we have nothing to copy */ data->toprint = 0; } } else { STRPTR text; if ((text = (STRPTR)GetTagData(GTTX_Text, (IPTR) NULL, msg->ops_AttrList))) { data->toprint = (IPTR)text; } } D(bug("calling text_set\n")); text_set(cl, o, msg); if (data->flags & TEXTF_BORDER) { struct TagItem frame_tags[] = { {IA_Width , GetTagData(GA_Width, 0, msg->ops_AttrList) }, {IA_Height , GetTagData(GA_Height, 0, msg->ops_AttrList) }, {IA_Resolution , (data->dri->dri_Resolution.X << 16) + data->dri->dri_Resolution.Y }, {IA_FrameType , FRAME_BUTTON }, {IA_Recessed , TRUE }, {TAG_DONE , 0UL } }; data->frame = NewObjectA(NULL, FRAMEICLASS, frame_tags); } } ReturnPtr ("Text::New", IPTR, (IPTR)o); error: CoerceMethod(cl, o, OM_DISPOSE); ReturnPtr ("Text::New", IPTR, (IPTR) NULL); }