>>>>>>>>>>>>>>>>>>>>> Progress box setup and cleanup <<<<<<<<<<<<<<<<<<<<< /*------------------------------*/ /* beg_prog */ /*------------------------------*/ VOID beg_prog(rect) GRECT *rect; { OBJECT *tree; WORD xdial, ydial, wdial, hdial; rsrc_gaddr(R_TREE, PROGRESS, &tree); form_center(tree, &rect->g_x, &rect->g_y, &rect->g_w, &rect->g_h); form_dial(0, 0, 0, 0, 0, rect->g_x, rect->g_y, rect->g_w, rect->g_h); objc_draw(tree, ROOT, MAX_DEPTH, rect->g_x, rect->g_y, rect->g_w, rect->g_h); } /*------------------------------*/ /* end_prog */ /*------------------------------*/ VOID end_prog(rect) GRECT *rect; { form_dial(3, 0, 0, 0, 0, rect->g_x, rect->g_y, rect->g_w, rect->g_h); } >>>>>>>>>>>>>>>>>>>> Text line progress indicator <<<<<<<<<<<<<<<<<<<<<<< /*------------------------------*/ /* set_prog */ /*------------------------------*/ VOID set_prog(strno) UWORD strno; { OBJECT *tree; BYTE *saddr; rsrc_gaddr(R_TREE, STRINGS, &tree); saddr = (BYTE *) (tree + strno)->ob_spec; rsrc_gaddr(R_TREE, PROGRESS, &tree); set_text(tree, PLINE, saddr); disp_obj(tree, PLINE); } >>>>>>>>>>>>>>>>>>>> Moving bar progress indicator <<<<<<<<<<<<<<<<<<<<<< /*------------------------------*/ /* set_prog */ /*------------------------------*/ VOID set_prog(value, maxc) WORD value, maxc; { WORD wnew, wold; OBJECT *tree; GRECT box; rsrc_gaddr(R_TREE, PROGRESS, &tree); wold = (tree + PROBOX)->ob_width - 1; /* Take border into account */ wnew = wold + 1; if (maxc) wnew = max(1, ((LONG) value * (LONG) wnew) / maxc); (tree + PROBAR)->ob_width = wnew; if (value) { objc_xywh(tree, PROBAR, &box); box.g_x += wold; box.g_w -= wold; objc_draw(tree, ROOT, MAX_DEPTH, box.g_x, box.g_y, box.g_w, box.g_h); } } >>>>>>>>>>>>>>>>>>>> Progress indicator check for abort <<<<<<<<<<<<<<<< /*------------------------------*/ /* esc_prog */ /*------------------------------*/ WORD esc_prog() { WORD which, kr; WORD mx, my, mb, ks, br; /* Not used, but needed */ FOREVER { which = evnt_multi(MU_KEYBD | MU_TIMER, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0L, 0, 0, /* Zero timer delay */ &mx, &my, &mb, &ks, &kr, &br); if (which & MU_KEYBD) { if ((kr & 0xff) == 0x1B) /* ESC? */ return (TRUE); /* else try again */ } else /* if (which & MU_TIMER) */ return (FALSE); } return (TRUE); /* Keeps lint happy */ } >>>>>>>>>>>>>>>>>>>>>>> Progress subroutines <<<<<<<<<<<<<<<<<<<<<<< VOID set_text(tree, obj, str) OBJECT *tree; BYTE *str; WORD obj; { TEDINFO *obspec; obspec = (TEDINFO *) (tree + obj)->ob_spec; /* Get TEDINFO address */ obspec->te_ptext = str; /* Set new text pointer */ obspec->te_txtlen = strlen(str); /* Set new length */ } VOID disp_obj(tree, obj) OBJECT *tree; WORD obj; { GRECT box; objc_xywh(tree, obj, &box); objc_draw(tree, ROOT, MAX_DEPTH, box.g_x, box.g_y, box.g_w, box.g_h); } VOID objc_xywh(tree, obj, p) /* get x,y,w,h for specified object */ OBJECT *tree; WORD obj; GRECT *p; { objc_offset(tree, obj, &p->g_x, &p->g_y); p->g_w = (tree + obj)->ob_width; p->g_h = (tree + obj)->ob_height; } >>>>>>>>>>>>>>>>>>>>>> Box mover examples <<<<<<<<<<<<<<<<<<<<<<<<<< /*------------------------------*/ /* fourway_box */ /*------------------------------*/ VOID fourway_box(vdi_handle, rubber, limit) WORD vdi_handle; GRECT *rubber, *limit; { UWORD ox, oy, mx, my, foo, down; vswr_mode(vdi_handle, MD_XOR); /* Set VDI modes for box */ vsl_color(vdi_handle, BLACK); wind_update(BEG_MCTRL); /* Capture mouse */ ox = rubber->g_x; oy = rubber->g_y; /* Save off input corner */ graf_mkstate(&mx, &my, &foo, &foo); /* Initialize mouse posn */ do { rubber->g_x = min(ox, mx); /* Choose UL corner */ rubber->g_y = min(oy, my); rubber->g_w = max(ox, mx) - rubber->g_x + 1; rubber->g_h = max(oy, my) - rubber->g_y + 1; rc_intersect(limit, rubber); /* Lock into limit rect */ down = rub_wait(vdi_handle, rubber, &mx, &my); } while (down); wind_update(END_MCTRL); /* Release mouse to GEM */ } /*------------------------------*/ /* hot_dragbox */ /*------------------------------*/ WORD hot_dragbox(vdi_handle, box, limit, tree) WORD vdi_handle; GRECT *box, *limit; OBJECT *tree; { UWORD ox, oy, mx, my, foo, down; WORD hover_obj, ret_obj; vswr_mode(vdi_handle, MD_XOR); /* Set VDI modes for box */ vsl_color(vdi_handle, BLACK); wind_update(BEG_MCTRL); /* Capture mouse */ graf_mkstate(&mx, &my, &foo, &foo); /* Initialize mouse posn */ ox = min(box->g_w, max(0, mx - box->g_x) ); oy = min(box->g_h, max(0, my - box->g_y) ); hover_obj = NIL; do { box->g_x = mx - ox; box->g_y = my - oy; rc_constrain(limit, box); /* Lock into limit rect */ down = rub_wait(vdi_handle, box, &mx, &my); if (!inside(mx, my, limit)) ret_obj = NIL; else { ret_obj = objc_find(tree, ROOT, NIL, mx, my); if (ret_obj != NIL) if ( !(SELECTABLE & (tree + ret_obj)->ob_flags) ) ret_obj = NIL; } if (ret_obj != hover_obj) { if (hover_obj != NIL) objc_toggle(tree, hover_obj); hover_obj = ret_obj; if (hover_obj != NIL) objc_toggle(tree, hover_obj); } } while (down); wind_update(END_MCTRL); /* Release mouse to GEM */ if (hover_obj != NIL) objc_toggle(tree, hover_obj); return (hover_obj); } /*------------------------------*/ /* rub_wait */ /*------------------------------*/ WORD rub_wait(vdi_handle, box, mx, my) WORD vdi_handle; GRECT *box; WORD *mx, *my; { WORD which, kr; WORD mb, ks, br; /* Not used, but needed */ graf_mouse(M_OFF, 0x0L); vdi_xbox(vdi_handle, box); /* Draw waiting box */ graf_mouse(M_ON, 0x0L); which = evnt_multi(MU_BUTTON | MU_M1, 0x01, 0x01, 0x00, /* Wait for button up */ TRUE, *mx, *my, 1, 1, /* or mouse move */ 0, 0, 0, 0, 0, 0L, 0, 0, mx, my, &mb, &ks, &kr, &br); graf_mouse(M_OFF, 0x0L); vdi_xbox(vdi_handle, box); /* Take down waiting box */ graf_mouse(M_ON, 0x0L); return (!(which & MU_BUTTON)); /* TRUE if still dragging */ } >>>>>>>>>>>>>>>>>>>>>>>> Box Mover Utilities <<<<<<<<<<<<<<<<<<<<<<<<< VOID objc_toggle(tree, obj) OBJECT *tree; WORD obj; { WORD state, newstate; GRECT root, ob_rect; objc_xywh(tree, ROOT, &root); newstate = (tree + obj)->ob_state ^ SELECTED; objc_change(tree, obj, 0, root.g_x, root.g_y, root.g_w, root.g_h, newstate, 1); } VOID vdi_xbox(vdi_handle, pt) WORD vdi_handle; GRECT *pt; { WORD pxy[10]; vdi_bxpts(pt, pxy); vdi_xline(vdi_handle, 5, pxy); } VOID vdi_bxpts(pt, pxy) GRECT *pt; WORD *pxy; { pxy[0] = pt->g_x; pxy[1] = pt->g_y; pxy[2] = pt->g_x + pt->g_w - 1; pxy[3] = pt->g_y; pxy[4] = pt->g_x + pt->g_w - 1; pxy[5] = pt->g_y + pt->g_h - 1; pxy[6] = pt->g_x; pxy[7] = pt->g_y + pt->g_h - 1; pxy[8] = pt->g_x; pxy[9] = pt->g_y; } MLOCAL WORD hztltbl[2] = { 0x5555, 0xaaaa }; MLOCAL WORD verttbl[4] = { 0x5555, 0xaaaa, 0xaaaa, 0x5555 }; VOID vdi_xline(vdi_handle, ptscount, ppoints) WORD vdi_handle, ptscount, *ppoints; { WORD *linexy,i; WORD st; for ( i = 1; i < ptscount; i++ ) { if ( *ppoints == *(ppoints + 2) ) { st = verttbl[( (( *ppoints) & 1) | ((*(ppoints + 1) & 1 ) << 1))]; } else { linexy = ( *ppoints < *( ppoints + 2 )) ? ppoints : ppoints + 2; st = hztltbl[( *(linexy + 1) & 1)]; } vsl_udsty(vdi_handle, st); vsl_type(vdi_handle, 7); v_pline(vdi_handle, 2, ppoints); ppoints += 2; } vsl_type(vdi_handle, 1); } WORD rc_intersect(p1, p2) /* compute intersect of two rectangles */ GRECT *p1, *p2; { WORD tx, ty, tw, th; tw = min(p2->g_x + p2->g_w, p1->g_x + p1->g_w); th = min(p2->g_y + p2->g_h, p1->g_y + p1->g_h); tx = max(p2->g_x, p1->g_x); ty = max(p2->g_y, p1->g_y); p2->g_x = tx; p2->g_y = ty; p2->g_w = tw - tx; p2->g_h = th - ty; return( (tw > tx) && (th > ty) ); } VOID rc_union(p1, p2) GRECT *p1, *p2; { WORD tx, ty, tw, th; tw = max(p1->g_x + p1->g_w, p2->g_x + p2->g_w); th = max(p1->g_y + p1->g_h, p2->g_y + p2->g_h); tx = min(p1->g_x, p2->g_x); ty = min(p1->g_y, p2->g_y); p2->g_x = tx; p2->g_y = ty; p2->g_w = tw - tx; p2->g_h = th - ty; } VOID rc_constrain(pc, pt) GRECT *pc; GRECT *pt; { if (pt->g_x < pc->g_x) pt->g_x = pc->g_x; if (pt->g_y < pc->g_y) pt->g_y = pc->g_y; if ((pt->g_x + pt->g_w) > (pc->g_x + pc->g_w)) pt->g_x = (pc->g_x + pc->g_w) - pt->g_w; if ((pt->g_y + pt->g_h) > (pc->g_y + pc->g_h)) pt->g_y = (pc->g_y + pc->g_h) - pt->g_h; } BOOLEAN inside(x, y, pt) /* determine if x,y is in rectangle */ UWORD x, y; GRECT *pt; { if ( (x >= pt->g_x) && (y >= pt->g_y) && (x < pt->g_x + pt->g_w) && (y < pt->g_y + pt->g_h) ) return(TRUE); else return(FALSE); } /* inside */