IPTR GTCheckBox__GM_GOINACTIVE(Class *cl, struct Gadget *g, struct gpGoInactive *msg) { struct CheckBoxData *data; struct RastPort *rp; data = INST_DATA(cl, g); data->flags &= ~CF_MouseOverGad; rp = ObtainGIRPort(msg->gpgi_GInfo); if (rp) { drawimage(cl, g, rp, g->Flags & GFLG_SELECTED, FALSE); ReleaseGIRPort(rp); } return 0; }
IPTR AROSCycle__GM_GOINACTIVE(Class *cl, Object *o, struct gpGoInactive *msg) { struct RastPort *rport; EG(o)->Flags &= ~GFLG_SELECTED; rport = ObtainGIRPort(msg->gpgi_GInfo); if (rport) { struct gpRender rmsg = { GM_RENDER, msg->gpgi_GInfo, rport, GREDRAW_UPDATE }, *p_rmsg = &rmsg; DoMethodA(o, (Msg)p_rmsg); ReleaseGIRPort(rport); } return 0; }
IPTR AROSListview__OM_UPDATE(Class *cl, Object *o,struct opSet *msg) { IPTR retval = DoSuperMethodA(cl, o, (Msg)msg); struct LVData *data = INST_DATA(cl, o); retval += (IPTR)_OM_SET(cl, o, (struct opSet *)msg); /* If we have been subclassed, OM_UPDATE should not cause a GM_RENDER * because it would circumvent the subclass from fully overriding it. * The check of cl == OCLASS(o) should fail if we have been * subclassed, and we have gotten here via DoSuperMethodA(). */ if ( retval && (cl == OCLASS(o)) && (data->lvd_NotifyCount) ) { struct GadgetInfo *gi = ((struct opSet *)msg)->ops_GInfo; if (gi) { struct RastPort *rp = ObtainGIRPort(gi); if (rp) { struct IBox ibox; GetGadgetIBox(o, gi, &ibox); data->lvd_DamageOffset = 0; data->lvd_NumDamaged = NumVisible(&ibox, data->lvd_EntryHeight); D(bug("Major rerender: o=%d, n=%d\n", data->lvd_DamageOffset, data->lvd_NumDamaged) ); DoMethod(o, GM_RENDER, (IPTR) gi, (IPTR) rp, GREDRAW_UPDATE); ReleaseGIRPort(rp); } } } return retval; }
IPTR AROSCycle__GM_GOACTIVE(Class *cl, Object *o, struct gpInput *msg) { struct CycleData *data; struct RastPort *rport; IPTR retval; data = INST_DATA(cl, o); EG(o)->Flags |= GFLG_SELECTED; rport = ObtainGIRPort(msg->gpi_GInfo); if (rport) { struct gpRender rmsg = { GM_RENDER, msg->gpi_GInfo, rport, GREDRAW_UPDATE }, *p_rmsg = &rmsg; DoMethodA(o, (Msg)p_rmsg); ReleaseGIRPort(rport); retval = GMR_MEACTIVE; } else retval = GMR_NOREUSE; return retval; }
IPTR GTCheckBox__GM_GOACTIVE(Class *cl, struct Gadget *g, struct gpInput *msg) { struct CheckBoxData *data; struct RastPort *rp; IPTR retval; data = INST_DATA(cl, g); data->flags |= CF_MouseOverGad; rp = ObtainGIRPort(msg->gpi_GInfo); if (rp) { drawimage(cl, g, rp, (g->Flags&GFLG_SELECTED) ? FALSE : TRUE, FALSE); ReleaseGIRPort(rp); retval = GMR_MEACTIVE; } else { retval = GMR_NOREUSE; } return retval; }
IPTR AROSCycle__GM_HANDLEINPUT(Class *cl, Object *o, struct gpInput *msg) { struct RastPort *rport; struct CycleData *data; IPTR retval = GMR_MEACTIVE; data = INST_DATA(cl, o); if (msg->gpi_IEvent->ie_Class == IECLASS_RAWMOUSE) { if (msg->gpi_IEvent->ie_Code == SELECTUP) { if (G(o)->Flags & GFLG_SELECTED) { /* mouse is over gadget */ data->active++; if (data->active == data->numlabels) data->active = 0; *msg->gpi_Termination = data->active; retval = GMR_NOREUSE | GMR_VERIFY; } else /* mouse is not over gadget */ retval = GMR_NOREUSE; /* G(o)->Flags &= ~GFLG_SELECTED; rport = ObtainGIRPort(msg->gpi_GInfo); if (rport) { struct gpRender rmsg = { GM_RENDER, msg->gpi_GInfo, rport, GREDRAW_UPDATE }; DoMethodA(o, (Msg)&rmsg); ReleaseGIRPort(rport); }*/ } else if (msg->gpi_IEvent->ie_Code == IECODE_NOBUTTON) { struct gpHitTest htmsg = { GM_HITTEST, msg->gpi_GInfo, { msg->gpi_Mouse.X, msg->gpi_Mouse.Y }, }, *p_htmsg = &htmsg; if (DoMethodA(o, (Msg)p_htmsg) != GMR_GADGETHIT) { if (EG(o)->Flags & GFLG_SELECTED) { G(o)->Flags &= ~GFLG_SELECTED; rport = ObtainGIRPort(msg->gpi_GInfo); if (rport) { struct gpRender rmsg = { GM_RENDER, msg->gpi_GInfo, rport, GREDRAW_UPDATE }, *p_rmsg = &rmsg; DoMethodA(o, (Msg)p_rmsg); ReleaseGIRPort(rport); } } } else { if (!(EG(o)->Flags & GFLG_SELECTED)) { EG(o)->Flags |= GFLG_SELECTED; rport = ObtainGIRPort(msg->gpi_GInfo); if (rport) { struct gpRender rmsg = { GM_RENDER, msg->gpi_GInfo, rport, GREDRAW_UPDATE }, *p_rmsg = &rmsg; DoMethodA(o, (Msg)p_rmsg); ReleaseGIRPort(rport); } } } } else if (msg->gpi_IEvent->ie_Code == MENUDOWN) retval = GMR_REUSE; } return retval; }
IPTR AROSCycle__OM_SET(Class *cl, Object *o, struct opSet *msg) { struct CycleData *data = INST_DATA(cl, o); const struct TagItem *tag, *taglist = msg->ops_AttrList; STRPTR *mylabels; BOOL rerender = FALSE; IPTR result; result = DoSuperMethodA(cl, o, (Msg)msg); while((tag = NextTagItem(&taglist))) { switch(tag->ti_Tag) { case AROSCYCLE_Labels: data->labels = (STRPTR *)tag->ti_Data; data->numlabels = 0; data->active = 0; mylabels = data->labels; if (mylabels) { while (mylabels[0]) { data->numlabels++; mylabels++; } } rerender = TRUE; break; case AROSCYCLE_Active: data->active = tag->ti_Data; rerender = TRUE; break; case GA_Disabled: rerender = TRUE; break; } } /* SDuvan: Removed test (cl == OCLASS(o)) */ if(rerender) { struct RastPort *rport; if(data->active > data->numlabels-1) data->active = 0; //kprintf("Rerendering\n"); rport = ObtainGIRPort(msg->ops_GInfo); if(rport) { DoMethod(o, GM_RENDER, (IPTR)msg->ops_GInfo, (IPTR)rport, GREDRAW_UPDATE); ReleaseGIRPort(rport); result = FALSE; } } return result; }
// 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; }
// Render listview void listview_render( Class *cl, struct Gadget *gadget, ListViewData *data, struct gpRender *render) { struct RastPort *rp; UWORD *pens; // Get rastport to use rp=(render->MethodID==GM_RENDER)?render->gpr_RPort:ObtainGIRPort(render->gpr_GInfo); // Get pen array pens=render->gpr_GInfo->gi_DrInfo->dri_Pens; // Set font SetFont(rp,data->list_font); // Look at render type switch (render->gpr_Redraw) { // Draw the whole gadget? case GREDRAW_REDRAW: { struct TagItem tags[4]; short a; // Valid title? if (data->title[0]) { short y,x,len; // Get title length len=strlen(data->title); // Get x and y position for title if (data->layout_flags&PLACETEXT_LEFT) { x=gadget->LeftEdge-TextLength(rp,data->title,len)-8; y=gadget->TopEdge+2+rp->TxBaseline; } else { x=gadget->LeftEdge; y=(gadget->TopEdge-1-rp->TxHeight)+rp->TxBaseline; } // Draw title SetAPen(rp,pens[TEXTPEN]); SetDrMd(rp,JAM1); Move(rp,x,y); Text(rp,data->title,len); // Underscore? if (data->title_uscore>-1) { int pos,len; // Get position and length of underscore pos=TextLength(rp,data->title,data->title_uscore); len=TextLength(rp,data->title+data->title_uscore,1); // Draw it Move(rp,x+pos,y+1); Draw(rp,x+pos+len-1,y+1); } // Reset draw mode SetDrMd(rp,JAM2); } // Draw border around the list listview_border( cl, rp, pens, &data->list_dims, (data->flags&LVF_READ_ONLY)?IDS_SELECTED:IDS_NORMAL, (data->flags&LVF_THIN_BORDER)?THIN:THICK); // Draw scroller border if (data->scroller) { listview_border( cl, rp, pens, &data->scroller_dims, IDS_NORMAL, (data->flags&LVF_THIN_BORDER)?THIN:THICK); // Draw blank area inside scroller border SetAPen(rp,pens[BACKGROUNDPEN]); if (0 && data->flags&LVF_DISABLE_CHANGE) { RectFill(rp, data->scroller_dims.Left+((data->flags&LVF_THIN_BORDER)?1:2), data->scroller_dims.Top+1, data->scroller_dims.Left+data->scroller_dims.Width-((data->flags&LVF_THIN_BORDER)?2:3), data->scroller_dims.Top+data->scroller_dims.Height-2); data->flags&=~LVF_DISABLE_CHANGE; } else { if (data->flags&LVF_THIN_BORDER) { Move(rp, data->scroller_dims.Left+1, data->scroller_dims.Top+1); Draw(rp, data->scroller_dims.Left+1, data->scroller_dims.Top+data->scroller_dims.Height-2); Move(rp, data->scroller_dims.Left+data->scroller_dims.Width-2, data->scroller_dims.Top+1); Draw(rp, data->scroller_dims.Left+data->scroller_dims.Width-2, data->scroller_dims.Top+data->scroller_dims.Height-2); } Move(rp, data->scroller_dims.Left+2, data->scroller_dims.Top+1); Draw(rp, data->scroller_dims.Left+data->scroller_dims.Width-3, data->scroller_dims.Top+1); Draw(rp, data->scroller_dims.Left+data->scroller_dims.Width-3, data->scroller_dims.Top+data->scroller_dims.Height-2); Draw(rp, data->scroller_dims.Left+2, data->scroller_dims.Top+data->scroller_dims.Height-2); Draw(rp, data->scroller_dims.Left+2, data->scroller_dims.Top+1); Move(rp, data->scroller_dims.Left+3, data->scroller_dims.Top+1); Draw(rp, data->scroller_dims.Left+3, data->scroller_dims.Top+data->scroller_dims.Height-2); Move(rp, data->scroller_dims.Left+data->scroller_dims.Width-4, data->scroller_dims.Top+1); Draw(rp, data->scroller_dims.Left+data->scroller_dims.Width-4, data->scroller_dims.Top+data->scroller_dims.Height-2); } } // Draw list listview_draw_items(cl,gadget,rp,render->gpr_GInfo->gi_DrInfo,data,-1); // Fill out scroller tags if (data->scroller) { tags[0].ti_Tag=PGA_Total; tags[0].ti_Data=data->count; tags[1].ti_Tag=PGA_Visible; tags[1].ti_Data=data->lines; tags[2].ti_Tag=PGA_Top; tags[2].ti_Data=data->top; tags[3].ti_Tag=TAG_END; // Update scroller DoMethod( (Object *)data->scroller, OM_SET, tags, render->gpr_GInfo); // Refresh arrows for (a=0;a<2;a++) DoMethod( (Object *)data->arrows[a], GM_RENDER, render->gpr_GInfo, rp, GREDRAW_REDRAW); // Refresh scroller DoMethod( (Object *)data->scroller, GM_RENDER, render->gpr_GInfo, rp, GREDRAW_REDRAW); } // Disabled? if (gadget->Flags&GFLG_DISABLED) { unsigned short ghost[2]; // Set ghosting pattern ghost[0]=0x8888; ghost[1]=0x2222; SetAfPt(rp,ghost,1); SetAPen(rp,pens[SHADOWPEN]); SetDrMd(rp,JAM1); // Fill with ghosting pattern RectFill(rp, data->dims.Left, data->dims.Top, data->dims.Left+data->dims.Width-1, data->dims.Top+data->dims.Height-1); // Clear ghosting pattern SetAfPt(rp,0,0); } // Otherwise, clear any gap between text area and gadget else { SetAPen(rp,pens[BACKGROUNDPEN]); if (data->text_dims.Top>data->dims.Top+1) { RectFill(rp, data->text_dims.Left, data->dims.Top+1, data->text_dims.Left+data->text_dims.Width-1, data->text_dims.Top-1); } if (data->text_dims.Top+data->text_dims.Height-1< data->dims.Top+data->dims.Height-2) { RectFill(rp, data->text_dims.Left, data->text_dims.Top+data->text_dims.Height, data->text_dims.Left+data->text_dims.Width-1, data->dims.Top+data->dims.Height-2); } } } break; // Just refresh items case GREDRAW_UPDATE: { // Draw list listview_draw_items(cl,gadget,rp,render->gpr_GInfo->gi_DrInfo,data,data->last_sel); // Refresh scroller? if (data->last_sel==-1 && data->scroller) { struct TagItem tags[2]; // Fill out scroller tags tags[0].ti_Tag=PGA_Top; tags[0].ti_Data=data->top; tags[1].ti_Tag=TAG_END; // Update scroller DoMethod( (Object *)data->scroller, OM_SET, tags, render->gpr_GInfo); } } break; } // Do we need to free the rastport? if (render->MethodID!=GM_RENDER) ReleaseGIRPort(rp); }
IPTR AslProp__OM_SET(Class * cl, Object * o, struct opSet * msg) { struct AslPropData *data; const struct TagItem *tstate = msg->ops_AttrList; struct TagItem *ti; IPTR retval; BOOL rerender = FALSE; data = INST_DATA(cl, o); while((ti = NextTagItem(&tstate))) { switch(ti->ti_Tag) { case ASLSC_DeltaFactor: data->deltafactor = (LONG)ti->ti_Data; break; case ASLSC_Inc: case ASLSC_Dec: if (((LONG)ti->ti_Data > 0) && (((struct opUpdate *)msg)->opu_Flags & OPUF_INTERIM)) { IPTR top, total, visible, newtop; GetAttr(PGA_Top, o, &top); GetAttr(PGA_Total, o, &total); GetAttr(PGA_Visible, o, &visible); newtop = top; if (ti->ti_Data == ID_ARROWDEC) { if (newtop < data->deltafactor) { newtop = 0; } else { newtop -= data->deltafactor; } } else { if (top <= total - visible - data->deltafactor) { newtop += data->deltafactor; } else { newtop = total - visible; } } if (newtop != top) { struct TagItem set_tags [] = { {PGA_Top, newtop }, {TAG_DONE } }; struct opSet ops; ops.MethodID = OM_SET; ops.ops_AttrList = set_tags; ops.ops_GInfo = msg->ops_GInfo; DoMethodA(o, (Msg)&ops); /* rerender = TRUE; */ } } /* if ((ti->ti_Data > 0) && (((struct opUpdate *)msg)->opu_Flags & OPUF_INTERIM)) */ } /* switch(ti->ti_Tag) */ } /* while((ti = NextTagItem(&tstate))) */ retval = DoSuperMethodA(cl, o, (Msg) msg); if (rerender) { struct RastPort *rp; rp = ObtainGIRPort(msg->ops_GInfo); if (NULL != rp) { DoMethod(o, GM_RENDER, (IPTR) msg->ops_GInfo, (IPTR) rp, GREDRAW_UPDATE); ReleaseGIRPort(rp); } } return retval; }
IPTR PUBLIC DispatchScrollerGadget(REG(a0, Class *cl), REG(a2, Object *o), REG(a1, Msg msg)) { struct ScrollerGData *sd; struct ClassBase *cb; IPTR retval = 0; sd = INST_DATA(cl,o); cb = (APTR)cl->cl_UserData; switch(msg->MethodID) { case OM_NEW: if ((retval = DoSuperMethodA(cl,o,msg)) != 0) { struct Gadget *gad = (struct Gadget *)retval; sd = INST_DATA(cl,retval); if (DispatchScrollerNew(cb,sd,gad,(struct opSet *)msg)) { //gad->NextGadget = sd->sd_Down; SetAttrs((APTR)retval,GA_Left, gad->LeftEdge+4, GA_Top, gad->TopEdge+2, GA_Width, gad->Width-8, GA_Height, gad->Height-2*sd->sd_UpImage->Height-4, PGA_Total, GetTagData(PGA_Total,0,((struct opSet *)msg)->ops_AttrList), GA_RelVerify, TRUE, TAG_END); } else { DoMethod(o,OM_DISPOSE); retval = 0; } } break; case OM_UPDATE: { struct opUpdate *opu = (APTR)msg; long move = 0; retval = DoSuperMethodA(cl,o,msg); if ((move = -GetTagData(SGA_Up,0,opu->opu_AttrList)) != 0) if (!(sd->sd_Up->Flags & GFLG_SELECTED)) move = 0; if (!move && (move = GetTagData(SGA_Down,0,opu->opu_AttrList))) if (!(sd->sd_Down->Flags & GFLG_SELECTED)) move = 0; if (move) { long top; if (GetAttr(PGA_Top,o,(IPTR *)&top)) { top += move; if (top >= 0) { struct RastPort *rp = ObtainGIRPort(opu->opu_GInfo); struct TagItem tags[] = {{PGA_Top,0},{TAG_END}}; SetAttrs(o,PGA_Top,top,TAG_END); GetAttr(PGA_Top,o,&tags[0].ti_Data); DoSuperMethod(cl,o,OM_NOTIFY,tags,opu->opu_GInfo,0); DoSuperMethod(cl,o,GM_RENDER,opu->opu_GInfo,rp,GREDRAW_UPDATE); ReleaseGIRPort(rp); } } } break; } case OM_DISPOSE: DisposeObject(sd->sd_UpImage); DisposeObject(sd->sd_DownImage); DisposeObject(sd->sd_Up); DisposeObject(sd->sd_Down); DisposeObject(sd->sd_Frame); retval = DoSuperMethodA(cl,o,msg); break; case GM_RENDER: { struct gpRender *gpr = (struct gpRender *)msg; DrawImage(gpr->gpr_RPort,sd->sd_Frame,0,0); retval = DoSuperMethodA(cl,o,msg); break; } default: retval = DoSuperMethodA(cl,o,msg); } return(retval); }
IPTR AROSListview__GM_GOACTIVE(Class *cl, Object *o, struct gpInput *msg) { IPTR retval = GMR_NOREUSE; struct LVData *data = INST_DATA(cl, o); struct IBox container; ULONG numentries; UWORD shown; /* pos of the selected inside the listview. Eg the first viewed has clickpos 0 */ UWORD clickpos; LONG active; UWORD activepos; WORD updateoldactive = -1; BOOL rerender = FALSE; BOOL singleclick = FALSE, doubleclick = FALSE; if (data->lvd_Flags & LVFLG_READONLY) goto exit; if (!msg->gpi_IEvent) goto exit; GetGadgetIBox(o, msg->gpi_GInfo, &container); GetAttr(AROSA_List_Entries, data->lvd_List, (IPTR *)&numentries); /* How many entries are currently shown in the listview ? */ shown = ShownEntries(data, &container); /* offset from top of listview of the entry clicked */ clickpos = (msg->gpi_Mouse.Y - LV_BORDERWIDTH_Y) / data->lvd_EntryHeight; data->lvd_Flags &= ~LVFLG_DOUBLECLICK; if (clickpos < shown) { GetAttr(AROSA_List_Active, data->lvd_List, (IPTR *)&active); /* Check for a doubleclick */ activepos = active - data->lvd_First; if (activepos == clickpos) { if (DoubleClick(data->lvd_StartSecs, data->lvd_StartMicros, msg->gpi_IEvent->ie_TimeStamp.tv_secs, msg->gpi_IEvent->ie_TimeStamp.tv_micro)) { data->lvd_Flags |= LVFLG_DOUBLECLICK; doubleclick = TRUE; D(bug("\tlv: doubleclick at pos %d\n", clickpos)); } } else { singleclick = TRUE; data->lvd_StartSecs = msg->gpi_IEvent->ie_TimeStamp.tv_secs; data->lvd_StartMicros = msg->gpi_IEvent->ie_TimeStamp.tv_micro; } if (data->lvd_Flags & LVFLG_MULTISELECT) { DoMethod ( data->lvd_List, AROSM_List_Select, data->lvd_First + clickpos, AROSV_List_Select_Toggle, (IPTR) NULL ); data->lvd_DamageOffset = clickpos; data->lvd_NumDamaged = 1; rerender = TRUE; } else { if (activepos != clickpos) { /* Active entry inside lv ? */ if ( (active >= data->lvd_First) && (active < (data->lvd_First + shown))) { updateoldactive = activepos; } data->lvd_DamageOffset = clickpos; data->lvd_NumDamaged = 1; rerender = TRUE; } /* if (not user reclicked on active entry) */ } /* if (lv is simple or multiselect) */ /* Render the selected-imagery of the new active item */ active = data->lvd_First + clickpos; SetAttrs(data->lvd_List, AROSA_List_Active, active, TAG_END); *(msg->gpi_Termination) = IDCMP_GADGETUP; D(bug("\t GMR_VERIFY retval set\n")); retval = GMR_NOREUSE|GMR_VERIFY; if (rerender) { struct RastPort *rp; rp = ObtainGIRPort(msg->gpi_GInfo); if (rp) { DoMethod(o, GM_RENDER, (IPTR) msg->gpi_GInfo, (IPTR) rp, GREDRAW_UPDATE); if (updateoldactive != -1) { data->lvd_DamageOffset = updateoldactive; data->lvd_NumDamaged = 1; DoMethod(o, GM_RENDER, (IPTR) msg->gpi_GInfo, (IPTR) rp, GREDRAW_UPDATE); } ReleaseGIRPort(rp); } } /* Tell subclasses that a singleclick occured */ if (singleclick) { DoMethod( o, AROSM_Listview_SingleClick, (IPTR) msg->gpi_GInfo, clickpos + data->lvd_First); } /* Tell subclasses that a doubleclick occured */ if (doubleclick) { DoMethod( o, AROSM_Listview_DoubleClick, (IPTR) msg->gpi_GInfo, clickpos + data->lvd_First); } } /* if (entry is shown) */ exit: 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); }
STATIC IPTR text_set(Class * cl, Object * o, struct opSet * msg) { IPTR retval = 0UL; struct TagItem *tag; const struct TagItem *tstate; struct TextData *data = INST_DATA(cl, o); struct RastPort *rport; EnterFunc(bug("Text::Set()\n")); tstate = msg->ops_AttrList; while ((tag = NextTagItem(&tstate))) { IPTR tidata = tag->ti_Data; switch (tag->ti_Tag) { case GTA_GadgetKind: data->gadgetkind = (WORD)tidata; break; case GTNM_Number: data->toprint = tidata; D(bug("GTNM_Number: %ld\n", tidata)); if (data->dispfunc) { #ifdef __MORPHOS__ REG_A7 -= 8; ((ULONG *)REG_A7)[0] = (ULONG)o; ((ULONG *)REG_A7)[1] = data->toprint; data->toprint = MyEmulHandle->EmulCallDirect68k(data->dispfunc); REG_A7 += 8; #else data->toprint = (ULONG)data->dispfunc((struct Gadget *)o, (WORD)data->toprint); #endif } retval = 1UL; break; case GTTX_Text: /* If the user has GT_SetGadgetAttrs() us to a different text, ** then don't copy it anymore */ if (msg->MethodID != OM_NEW) { if (data->flags & TEXTF_COPYTEXT) { FreeVec((APTR)data->toprint); data->flags &= ~TEXTF_COPYTEXT; } data->toprint = tidata; D(bug("GTTX_Text: %s\n", tidata)); } retval = 1UL; break; case GTTX_Border: /* [I] */ case GTNM_Border: /* [I] */ if (tidata) data->flags |= TEXTF_BORDER; D(bug("Border: %d\n", tidata)); break; /*case GTTX_FrontPen: [IS] */ case GTNM_FrontPen: /* [IS] */ data->frontpen = (UBYTE)tidata; D(bug("FrontPen: %d\n", tidata)); retval = 1UL; break; /* case GTTX_BackPen: [IS] */ case GTNM_BackPen: /* [IS] */ data->backpen = (UBYTE)tidata; D(bug("BackPen: %d\n", tidata)); retval = 1UL; break; /* case GTTX_Justification: [I] */ case GTNM_Justification: /* [I] */ data->justification = (UBYTE)tidata; D(bug("Justification: %d\n", tidata)); break; case GTNM_Format: /* [I] */ case GTA_Text_Format: data->format = (STRPTR)tidata; D(bug("Format: %s\n", tidata)); break; /* case GTTX_Clipped: [I] */ case GTNM_Clipped: if (tidata) data->flags |= TEXTF_CLIPPED; D(bug("Clipped: %d\n", tidata)); break; case GTNM_MaxNumberLen: /* [I] */ data->maxnumberlength = tidata; D(bug("MaxNumberLen: %d\n", tidata)); break; } /* switch() */ } /* while (iterate taglist) */ /* Redraw the gadget, if an attribute was changed and if this is the objects' base-class. */ if ((retval) && (OCLASS(o) == cl)) { rport = ObtainGIRPort(msg->ops_GInfo); if (rport) { DoMethod(o, GM_RENDER, (IPTR) msg->ops_GInfo, (IPTR) rport, GREDRAW_UPDATE); ReleaseGIRPort(rport); retval = FALSE; } } ReturnInt ("Text::Set", IPTR, retval); }
IPTR GTCheckBox__GM_HANDLEINPUT(Class *cl, struct Gadget *g, struct gpInput *msg) { struct CheckBoxData *data; struct RastPort *rp; IPTR retval = GMR_MEACTIVE; data = INST_DATA(cl, g); if (msg->gpi_IEvent->ie_Class == IECLASS_RAWMOUSE) { if (msg->gpi_IEvent->ie_Code == SELECTUP) { if (data->flags & CF_MouseOverGad) { /* mouse is over gadget */ g->Flags ^= GFLG_SELECTED; *msg->gpi_Termination = g->Flags&GFLG_SELECTED?TRUE:FALSE; retval = GMR_NOREUSE | GMR_VERIFY; } else { /* mouse is not over gadget */ retval = GMR_NOREUSE; } } else if (msg->gpi_IEvent->ie_Code == IECODE_NOBUTTON) { if ((msg->gpi_Mouse.X < 0) || (msg->gpi_Mouse.Y < 0) || (msg->gpi_Mouse.X >= g->Width ) || (msg->gpi_Mouse.Y >= g->Height)) { if (data->flags & CF_MouseOverGad) { rp = ObtainGIRPort(msg->gpi_GInfo); if (rp) { drawimage(cl, g, rp, g->Flags&GFLG_SELECTED, FALSE); ReleaseGIRPort(rp); } data->flags &= ~CF_MouseOverGad; } } else { if (!(data->flags & CF_MouseOverGad)) { rp = ObtainGIRPort(msg->gpi_GInfo); if (rp) { drawimage(cl, g, rp, (g->Flags&GFLG_SELECTED)?FALSE:TRUE, FALSE); ReleaseGIRPort(rp); } data->flags |= CF_MouseOverGad; } } } /* else if (msg->gpi_IEvent->ie_Code == IECODE_NOBUTTON) */ else if (msg->gpi_IEvent->ie_Code == MENUDOWN) { retval = GMR_NOREUSE; } } /* if (msg->gpi_IEvent->ie_Class == IECLASS_RAWMOUSE) */ return retval; }
IPTR GTCheckBox__OM_SET(Class *cl, struct Gadget *g, struct opSet *msg) { struct CheckBoxData *data; struct TagItem *tag; const struct TagItem *taglist = msg->ops_AttrList; struct RastPort *rp; IPTR retval = FALSE; data = INST_DATA(cl, g); if (data->flags & CF_CustomImage) { tag = FindTagItem(GA_Image, taglist); if (tag) { DisposeObject(g->GadgetRender); g->GadgetRender = NULL; data->flags &= ~CF_CustomImage; } } if (msg->MethodID != OM_NEW) retval = DoSuperMethodA(cl, (Object *)g, (Msg)msg); while ((tag = NextTagItem(&taglist))) { switch (tag->ti_Tag) { case GA_Disabled: retval = TRUE; break; case GA_DrawInfo: if (msg->MethodID == OM_NEW) data->dri = (struct DrawInfo *) tag->ti_Data; break; case GA_Image: case GA_SelectRender: retval = TRUE; break; case GA_LabelPlace: if (msg->MethodID == OM_NEW) data->labelplace = (LONG)tag->ti_Data; break; case GTCB_Checked: if (tag->ti_Data) g->Flags |= GFLG_SELECTED; else g->Flags &= ~GFLG_SELECTED; retval = TRUE; break; } /* switch (tag->ti_Tag) */ } /* while ((tag = NextTagItem(&taglist))) */ if (g->Width == 0) g->Width = CHECKBOX_WIDTH; if (g->Height == 0) g->Height = CHECKBOX_HEIGHT; /* Redraw ourself? */ if ((retval) && (msg->MethodID != OM_NEW) && ((msg->MethodID != OM_UPDATE) || (OCLASS(g) == cl))) { rp = ObtainGIRPort(msg->ops_GInfo); if (rp) { DoMethod((Object *)g, GM_RENDER, (IPTR) msg->ops_GInfo, (IPTR) rp, GREDRAW_UPDATE); ReleaseGIRPort(rp); retval = FALSE; } } return retval; }