// Handle backdrop icon idcmp stuff BOOL backdrop_idcmp(BackdropInfo *info,struct IntuiMessage *msg,unsigned short flags) { BOOL handled=1; BOOL busy=0; // Lister locked? if (info->lister && info->lister->flags&LISTERF_LOCK) busy=1; // Message class? switch (msg->Class) { // Size change case IDCMP_NEWSIZE: backdrop_update_size(info); break; // Refresh window case IDCMP_REFRESHWINDOW: // If we haven't already refreshed if (!(info->flags&BDIF_REFRESHED)) { UWORD ref_flags; // Get flags for refreshing ref_flags=BDSF_REFRESH; if (!(flags&BIDCMPF_LISTER)) ref_flags|=BDSF_REFRESH_DONE; // From a resize? if (info->flags&BDIF_NEW_SIZE) ref_flags|=BDSF_RECALC; // Otherwise, check that size is ok else backdrop_check_size(info); // Refresh objects backdrop_show_objects(info,ref_flags); } // Clear flags info->flags&=~(BDIF_NEW_SIZE|BDIF_REFRESHED); // Got a lister? if (info->lister) { // Clear 'sized' flag in lister info->lister->flags&=~LISTERF_RESIZED; // Save event for lister too if (flags&BIDCMPF_LISTER) handled=0; } break; // Mouse moved case IDCMP_MOUSEMOVE: // Rubber banding? if (info->flags&BDIF_RUBBERBAND) { short x,y; // Get coordinates, clip to borders x=info->window->MouseX; y=info->window->MouseY; if (x<info->size.MinX) x=info->size.MinX; if (x>info->size.MaxX) x=info->size.MaxX; if (y<info->size.MinY) y=info->size.MinY; if (y>info->size.MaxY) y=info->size.MaxY; // Have coordinates changed? if (info->select.MaxX!=x || info->select.MaxY!=y) { // Erase old box backdrop_rubber_band(info,0); // New coordinates info->select.MaxX=x; info->select.MaxY=y; // Show new box backdrop_rubber_band(info,1); } break; } // Are we dragging something? else if (info->flags&BDIF_DRAGGING && info->last_sel_object) { // Show drag objects backdrop_show_drag( info, info->last_sel_object, info->window->WScreen->MouseX, info->window->WScreen->MouseY); break; } // No gadget down, or no real-time scrolling? if (!info->down_gadget || !(environment->env->display_options&DISPOPTF_REALTIME_SCROLL)) { // Not handled handled=0; break; } // Tick case IDCMP_INTUITICKS: // Tick? if (msg->Class==IDCMP_INTUITICKS) { // Increment tick count ++info->tick_count; // No gadget down? if (!info->down_gadget) { // Turn ticks off if not dragging if (!(info->flags&(BDIF_DRAGGING|BDIF_RUBBERBAND))) ModifyIDCMP(info->window,info->window->IDCMPFlags&~IDCMP_INTUITICKS); break; } // Ignore this gadget? if (info->flags&BDIF_IGNORE_GADGET) { info->flags&=~BDIF_IGNORE_GADGET; break; } } // Fake gadget down msg->IAddress=info->down_gadget; // Gadget down case IDCMP_GADGETDOWN: // Store gadget if (info->down_gadget!=(struct Gadget *)msg->IAddress) { info->down_gadget=(struct Gadget *)msg->IAddress; info->flags|=BDIF_IGNORE_GADGET; ModifyIDCMP(info->window,info->window->IDCMPFlags|IDCMP_INTUITICKS); } // Check gadget is selected if (!(info->down_gadget->Flags&GFLG_SELECTED)) break; // Look at gadget ID switch (info->down_gadget->GadgetID) { // Up arrow case GAD_VERT_ARROW_UP: backdrop_scroll(info,0,-1); break; // Down arrow case GAD_VERT_ARROW_DOWN: backdrop_scroll(info,0,1); break; // Left arrow case GAD_HORIZ_ARROW_LEFT: backdrop_scroll(info,-1,0); break; // Right arrow case GAD_HORIZ_ARROW_RIGHT: backdrop_scroll(info,1,0); break; // Vertical slider case GAD_VERT_SCROLLER: if (environment->env->display_options&DISPOPTF_REALTIME_SCROLL) backdrop_pos_slider(info,SLIDER_VERT); break; // Horizontal slider case GAD_HORIZ_SCROLLER: if (environment->env->display_options&DISPOPTF_REALTIME_SCROLL) backdrop_pos_slider(info,SLIDER_HORZ); break; } break; // Gadget up case IDCMP_GADGETUP: info->down_gadget=0; info->flags&=~BDIF_IGNORE_GADGET; ModifyIDCMP(info->window,info->window->IDCMPFlags&~IDCMP_INTUITICKS); // Look at gadget ID switch (((struct Gadget *)msg->IAddress)->GadgetID) { // Vertical slider case GAD_VERT_SCROLLER: backdrop_pos_slider(info,SLIDER_VERT); break; // Horizontal slider case GAD_HORIZ_SCROLLER: backdrop_pos_slider(info,SLIDER_HORZ); break; // Another gadget default: handled=0; break; } break; // Mouse buttons case IDCMP_MOUSEBUTTONS: // Ignore if busy if (busy) break; // Clear down gadget info->down_gadget=0; info->flags&=~BDIF_IGNORE_GADGET; ModifyIDCMP(info->window,info->window->IDCMPFlags&~IDCMP_INTUITICKS); // Handle button handled=backdrop_handle_button(info,msg,flags); // Remember the last button pushed info->last_button=msg->Code&~IECODE_UP_PREFIX; break; // Key press case IDCMP_RAWKEY: // Dragging something? if (info->flags&(BDIF_RUBBERBAND|BDIF_DRAGGING)) { // If escape is pressed, cancel drag if (msg->Code==0x45) backdrop_stop_drag(info); break; } // Title-barred lister? if (info->lister && info->lister->more_flags&LISTERF_TITLEBARRED) break; // Not handled by default handled=0; // Look at key switch (msg->Code) { // Space toggles icon selection case 0x40: // Lister not busy? if (!busy) { BackdropObject *object; // Lock backdrop list lock_listlock(&info->objects,1); // Turn off? if (info->flags&BDIF_KEY_SELECTION) { // See if current selection is still valid if ((object=find_backdrop_object(info,info->current_sel_object))) { // Clear selection flag and redraw object->flags&=~BDOF_SELECTED; backdrop_render_object(info,object,BRENDERF_CLIP); } // Clear selection pointer info->current_sel_object=0; info->flags&=~BDIF_KEY_SELECTION; } // Turn on else { // Sort objects into position order backdrop_sort_objects(info,0,0); // Get first object object=(BackdropObject *)info->objects.list.lh_Head; if (object->node.ln_Succ) { // Set selection flag in new object and render object->flags|=BDOF_SELECTED; backdrop_render_object(info,object,BRENDERF_CLIP); // Store object pointer info->current_sel_object=object; info->flags|=BDIF_KEY_SELECTION; } } // Unlock backdrop list unlock_listlock(&info->objects); handled=1; } break; // Cursor keys changes selection case CURSORUP: case CURSORDOWN: case CURSORLEFT: case CURSORRIGHT: // In selection mode? if (!busy && info->flags&BDIF_KEY_SELECTION) { BackdropObject *object=0,*lastobject; short horiz=0; // Lock backdrop list lock_listlock(&info->objects,1); // Horizontal movement? if (msg->Code==CURSORLEFT || msg->Code==CURSORRIGHT) horiz=BSORT_HORIZ; // Need to resort? if ((horiz && !(info->flags&BDIF_LAST_SORT_HORIZ)) || (!horiz && info->flags&BDIF_LAST_SORT_HORIZ)) { // Sort objects into position order backdrop_sort_objects(info,horiz,0); } // See if current selection is still valid if ((lastobject=find_backdrop_object(info,info->current_sel_object))) { // Down or right, get next object if (msg->Code==CURSORDOWN || msg->Code==CURSORRIGHT) object=(BackdropObject *)lastobject->node.ln_Succ; // Up or left, get previous object else object=(BackdropObject *)lastobject->node.ln_Pred; } // Invalid object? if (!object || !object->node.ln_Succ || !object->node.ln_Pred) { // Get first (or last) selection if (object && !object->node.ln_Pred) object=(BackdropObject *)info->objects.list.lh_TailPred; else object=(BackdropObject *)info->objects.list.lh_Head; } // New object different from last? if (object!=info->current_sel_object) { // Was there an old selection? if (lastobject) { // Clear selection flag and redraw lastobject->flags&=~BDOF_SELECTED; backdrop_render_object(info,lastobject,BRENDERF_CLIP); } // New valid object? if (object) { // Make sure object is visible backdrop_make_visible(info,object); // Set selection flag in new object and render object->flags|=BDOF_SELECTED; backdrop_render_object(info,object,BRENDERF_CLIP); } // Store object pointer info->current_sel_object=object; } // Unlock backdrop list unlock_listlock(&info->objects); handled=1; } break; // Return opens an icon case 0x44: // In selection mode? if (!busy && info->flags&BDIF_KEY_SELECTION) { BackdropObject *object; // Lock backdrop list lock_listlock(&info->objects,0); // See if current selection is still valid if ((object=find_backdrop_object(info,info->current_sel_object))) { // Open object info->last_sel_object=object; backdrop_object_open(info,object,msg->Qualifier,1,0,0); // Clear selection pointers info->current_sel_object=0; info->last_sel_object=0; info->flags&=~BDIF_KEY_SELECTION; // Deselect object object->flags&=~BDOF_SELECTED; backdrop_render_object(info,object,BRENDERF_CLIP); } // Unlock backdrop list unlock_listlock(&info->objects); handled=1; } break; // Page up/Page down case PAGEUP: case PAGEDOWN: { ULONG oldpos,pos; long newpos,diff; // Get old position GetAttr(PGA_Top,info->vert_scroller,&oldpos); // Get new position newpos=info->offset_y-info->area.MinY; if (msg->Code==PAGEUP) newpos-=(info->size.MaxY-info->size.MinY)+1; else newpos+=(info->size.MaxY-info->size.MinY)+1; if (newpos<0) newpos=0; // Update gadget SetGadgetAttrs(info->vert_scroller,info->window,0, PGA_Top,newpos, TAG_END); // Get new position GetAttr(PGA_Top,info->vert_scroller,&pos); // Change? diff=oldpos-pos; if (diff<0) diff=-diff; if (diff>2) { // Update screen backdrop_pos_slider(info,SLIDER_VERT); } handled=1; } break; // Home/End case HOME: case END: { ULONG oldpos,pos; long diff; // Get old position GetAttr(PGA_Top,info->horiz_scroller,&oldpos); // Update gadget SetGadgetAttrs(info->horiz_scroller,info->window,0, PGA_Top,(msg->Code==HOME)?0:0xfffffff, TAG_END); // Get new position GetAttr(PGA_Top,info->horiz_scroller,&pos); // Change? diff=oldpos-pos; if (diff<0) diff=-diff; if (diff>2) { // Update screen backdrop_pos_slider(info,SLIDER_HORZ); } handled=1; } break; } break; // Not handled default: handled=0; break; } return handled; }
// Stop dragging BOOL backdrop_stop_drag(BackdropInfo *info) { BackdropObject *object; BOOL ret=0; // Rubber-banding? if (info->flags&BDIF_RUBBERBAND) { // Erase box backdrop_rubber_band(info,0); // Clear flag and mouse reporting info->flags&=~BDIF_RUBBERBAND; info->window->Flags&=~(WFLG_REPORTMOUSE|WFLG_RMBTRAP); // Turn ticks off ModifyIDCMP(info->window,info->window->IDCMPFlags&~IDCMP_INTUITICKS); // If icon positioning, unlock layers if (GUI->flags&GUIF_DRAGGING) { UnlockLayers(&info->window->WScreen->LayerInfo); GUI->flags&=~GUIF_DRAGGING; } } // Dragging? else if (info->flags&BDIF_DRAGGING) { // Clear drag flag info->flags&=~BDIF_DRAGGING; // Are we dragging? if (GUI->flags&GUIF_DRAGGING) { ULONG sec,mic,mic1,mic2; // Get stop time CurrentTime(&sec,&mic); // Normal dragging? if (!(info->flags&BDIF_CUSTOM_DRAG)) { // Go through backdrop list for (object=(BackdropObject *)info->objects.list.lh_Head; object->node.ln_Succ; object=(BackdropObject *)object->node.ln_Succ) { // Is object being dragged? if (object->drag_info) { // Hide object RemBob(&object->drag_info->bob); } } } // Draw GELs list SortGList(&GUI->drag_screen_rp); DrawDragList(&GUI->drag_screen_rp,&info->window->WScreen->ViewPort,(info->flags&BDIF_CUSTOM_DRAG)?DRAGF_CUSTOM|DRAGF_REMOVE:0); // Clear drag flag GUI->flags&=~GUIF_DRAGGING; // Unlock layer UnlockLayers(&info->window->WScreen->LayerInfo); // Get drag time deltas mic1=(sec*1000000)+mic; mic2=(info->drag_sec*1000000)+info->drag_mic; // If drag was less than a fifth of a second, nothing moves if (mic1<mic2+200000) ret=1; } // Go through backdrop list for (object=(BackdropObject *)info->objects.list.lh_Head; object->node.ln_Succ; object=(BackdropObject *)object->node.ln_Succ) { // Was object being dragged? if (object->drag_info) { // Free drag FreeDragInfo(object->drag_info); object->drag_info=0; } } // Start menu actions, stop mouse reporting info->window->Flags&=~(WFLG_RMBTRAP|WFLG_REPORTMOUSE); // Turn ticks off ModifyIDCMP(info->window,info->window->IDCMPFlags&~IDCMP_INTUITICKS); // Unlock backdrop list unlock_listlock(&info->objects); } return ret; }