/*========================================================================== * FILE: SAMPLE.C *========================================================================== * DATE: November 8, 1990 * DESCRIPTION: SAMPLE CPX demonstrating the use of the popup and slider * functions in a FORM-TYPE CPX. * COMPILER: Mark Williams C */ /* INCLUDE FILES *========================================================================== */ #include #include #include #include #include #include #include "sample.h" #include "sample.rsh" #include "cpxdata.h" /* Our CPX Data Structures */ /* PROTOTYPES *========================================================================== */ CPXINFO *cpx_init(); BOOLEAN cpx_call(); void initialize(); int handle_button(); void VDraw(); void HDraw(); int Pop_Handle(); /* DEFINES *========================================================================== */ #define NUM_ITEMS 5 /* # of items for the popup. */ #define MAX_ITEMS 12 /* Upper limit for slider value. */ #define MIN_ITEMS 0 /* Lower limit for slider value */ #define AAAA 0 /* Start with the first index */ #define INIT_VALUE 6 /* Initial value for sliders */ /* EXTERNALS *========================================================================== */ extern int save_vars; /* GLOBALS *========================================================================== */ XCPB *xcpb; /* XControl Parameter Block */ CPXINFO cpxinfo; /* CPX Information Structure */ OBJECT *tree; /* Our resource object tree */ GRECT desk; /* GRECT of the desktop work area */ char blanks[5][30]; /* Used for Pop_Up String Builds */ char *blank[5]; char *menu_items[] = { "AAAA", /* The text for the popup button. */ "BBBB", "CCCC", "DDDD", "EEEE" }; BOOLEAN click_flag = FALSE; /* Double click flag */ int cur_item; /* Current popup menu item ( zero based )*/ char vcur_text[3]; /* Text Strings for current slider values*/ char hcur_text[3]; int vcur_item; /* Current Slider Values */ int hcur_item; MFORM Mbuffer; /* Mouse background image storage */ int errno; /***** GLOBAL VARIABLES FOR VDI ***/ WORD contrl[12]; WORD intin[128]; WORD ptsin[128]; WORD intout[128]; WORD ptsout[128]; /* FUNCTIONS *========================================================================== */ /* cpx_init() *========================================================================== * cpx_init() is where a CPX is first initialized. * There are TWO parts. * * PART ONE: cpx_init() is called when the CPX is first 'booted'. This is * where the CPX should read in its defaults and then set the * hardware based on those defaults. * * PART TWO: The other time cpx_init() is called is when the CPX is being * executed. This is where the resource is fixed up and current * cpx variables are updated from the hardware. In addition, * this is where the CPXINFO structure should be filled out. * * IN: XCPB *Xcpb: Pointer to the XControl Parameter Block * OUT: CPXINFO *ptr: Pointer to the CP Information Structure */ CPXINFO *cpx_init( Xcpb ) XCPB *Xcpb; { xcpb = Xcpb; appl_init(); /* Only those CPXs with their 'Booting' flag or 'Set-only' flag * set will be initialized here. * * Read in your defaults from 'save_vars' and slam them into * the hardware where appropriate. * * Return TRUE to tell XCONTROL that the header should be retained * so that the cpx may be executed. * * Return FALSE to tell XCONTROL NOT to retain our header. * An example of this would be a 'Set-Only' CPX. */ if( xcpb->booting ) return( ( CPXINFO *)TRUE ); else { /* Fixup the resource... * The flag prevents rsh_fix() from being called more than once. * If executing from disk, rsh_fix() is called every time. However, * If the CPX is 'resident', rsh_fix() will be called only once. */ if( !xcpb->SkipRshFix ) (*xcpb->rsh_fix)( NUM_OBS, NUM_FRSTR, NUM_FRIMG, NUM_TREE, rs_object, rs_tedinfo, rs_strings, rs_iconblk, rs_bitblk, rs_frstr, rs_frimg, rs_trindex, rs_imdope ); tree = ( OBJECT *)rs_trindex[ MAINTREE ]; /* Initialize the CPXINFO structure */ cpxinfo.cpx_call = cpx_call; cpxinfo.cpx_draw = NULL; cpxinfo.cpx_wmove = NULL; cpxinfo.cpx_timer = NULL; cpxinfo.cpx_key = NULL; cpxinfo.cpx_button = NULL; cpxinfo.cpx_m1 = NULL; cpxinfo.cpx_m2 = NULL; cpxinfo.cpx_hook = NULL; cpxinfo.cpx_close = NULL; return( &cpxinfo ); } } /* cpx_call() *========================================================================== * Called when a CPX is invoked AFTER the cpx_init() call has been * completed. The function is passed a rectangle describing the current * work area of the XControl window. This allows a CPX to set up for * a user interaction and optionally call the custom xform_do() routine * to handle its user interface. * * * IN: GRECT *rect: Ptr to a GRECT that describes the current work * area of the XControl window. * * OUT: * FALSE: The CPX has exited and no more messages are * needed. XControl will either return to its * main menu or close its windows. * This is used by XForm_do() type CPXs. * * TRUE: The CPX requests that XCONTROL continue to * send AES messages. This is used by EVENT-TYPE CPXs. */ BOOLEAN cpx_call( rect ) GRECT *rect; { int button; int quit = 0; WORD msg[8]; ObX( ROOT ) = rect->g_x; ObY( ROOT ) = rect->g_y; initialize(); wind_get( 0, WF_WORKXYWH, &desk.g_x, &desk.g_y, &desk.g_w, &desk.g_h ); objc_draw( tree, ROOT, MAX_DEPTH, PTRS( rect ) ); do { button = (*xcpb->Xform_do)( tree, 0, msg ); quit = handle_button( button, msg ); }while( !quit); return( FALSE ); } /* initialize() *========================================================================== * Initialize the slider and popup values and calculate * the slider positions. * * IN: none * * OUT: none */ void initialize() { cur_item = save_vars; TedText( POPUP ) = menu_items[ cur_item ]; vcur_item = hcur_item = INIT_VALUE; sprintf( vcur_text, "%d", vcur_item ); TedText( SLIDEV ) = vcur_text; ( *xcpb->Sl_y)( tree, BASEV, SLIDEV, vcur_item, MAX_ITEMS, MIN_ITEMS, NULLFUNC ); sprintf( hcur_text, "%d", hcur_item ); TedText( SLIDEH ) = hcur_text; ( *xcpb->Sl_x)( tree, BASEH, SLIDEH, hcur_item, MIN_ITEMS, MAX_ITEMS, NULLFUNC ); } /* handle_button() *========================================================================== * Perform button click handling * * IN: int button: AES object clicked on. * WORD: *msg: message array returned from the event_multi(). * * OUT: int quit: Returns value to cpx_call(). * FALSE - don't quit cpx * TRUE - quit the cpx and return to XControl. * */ int handle_button( button, msg ) int button; WORD *msg; { int quit = FALSE; int obj; MRETS mk; int ox,oy; GRECT rect; /* Check if we have a double click item */ if( ( button != -1 ) && ( button & 0x8000 ) ) { click_flag = TRUE; button &= 0x7FFF; } switch( button ) { case QUIT: quit = TRUE; (*xcpb->CPX_Save)( &cur_item, 2L ); Deselect( QUIT ); break; case POPUP: obj = Pop_Handle( tree, POPUP, menu_items, NUM_ITEMS, &cur_item, IBM ); if( obj != -1 ) { cur_item = obj; TedText( POPUP ) = menu_items[ cur_item ]; } Deselect( POPUP ); rect = ObRect( POPUP ); objc_offset( tree, POPUP, &rect.g_x, &rect.g_y ); objc_draw( tree, POPUP, MAX_DEPTH, ELTS( rect ) ); break; case UP: (*xcpb->Sl_arrow)( tree, BASEV, SLIDEV, UP, -1, MAX_ITEMS, MIN_ITEMS, &vcur_item, VERTICAL, VDraw ); break; case DOWN: (*xcpb->Sl_arrow)( tree, BASEV, SLIDEV, DOWN, 1, MAX_ITEMS, MIN_ITEMS, &vcur_item, VERTICAL, VDraw ); break; case BASEV: graf_mkstate( &mk.x, &mk.y, &mk.buttons, &mk.kstate ); objc_offset( tree, SLIDEV, &ox, &oy ); ox = (( mk.y < oy ) ? ( -2 ) : ( 2 ) ); (*xcpb->Sl_arrow)( tree, BASEV, SLIDEV, -1, ox, MAX_ITEMS, MIN_ITEMS, &vcur_item, VERTICAL, VDraw ); break; case SLIDEV: (*xcpb->MFsave)( MFSAVE, &Mbuffer ); graf_mouse( FLAT_HAND, 0L ); (*xcpb->Sl_dragy)( tree, BASEV, SLIDEV, MAX_ITEMS, MIN_ITEMS, &vcur_item, VDraw ); (*xcpb->MFsave)( MFRESTORE, &Mbuffer ); break; case LEFT: (*xcpb->Sl_arrow)( tree, BASEH, SLIDEH, LEFT, -1, MIN_ITEMS, MAX_ITEMS, &hcur_item, HORIZONTAL, HDraw ); break; case RIGHT: (*xcpb->Sl_arrow)( tree, BASEH, SLIDEH, RIGHT, 1, MIN_ITEMS, MAX_ITEMS, &hcur_item, HORIZONTAL, HDraw ); break; case BASEH: graf_mkstate( &mk.x, &mk.y, &mk.buttons, &mk.kstate ); objc_offset( tree, SLIDEH, &ox, &oy ); oy = (( mk.x < ox ) ? ( -2 ) : ( 2 ) ); (*xcpb->Sl_arrow)( tree, BASEH, SLIDEH, -1, oy, MIN_ITEMS, MAX_ITEMS, &hcur_item, HORIZONTAL, HDraw ); break; case SLIDEH: (*xcpb->MFsave)( MFSAVE, &Mbuffer ); graf_mouse( FLAT_HAND, 0L ); (*xcpb->Sl_dragx)( tree, BASEH, SLIDEH, MIN_ITEMS, MAX_ITEMS, &hcur_item, HDraw ); (*xcpb->MFsave)( MFRESTORE, &Mbuffer ); break; default: if( button == -1 ) { switch( msg[0] ) { case AC_CLOSE: case WM_CLOSED: quit = TRUE; break; case WM_REDRAW: case CT_KEY: break; default: break; } } break; } return( quit ); } /* VDraw() *========================================================================== * Convert the vertical slider value to a string, update the rcs * structure, and redraw the string. * * GLOBAL: int vcur_item: * char vcur_text[]: * OBJECT *tree: * * IN: none * OUT: none */ void VDraw() { GRECT rect; sprintf( vcur_text, "%d", vcur_item ); TedText( SLIDEV ) = vcur_text; rect = ObRect( SLIDEV ); objc_offset( tree, SLIDEV, &rect.g_x, &rect.g_y ); objc_draw( tree, SLIDEV, MAX_DEPTH, ELTS( rect ) ); } /* HDraw() *========================================================================== * Convert the horizontal slider value to a string, update the rcs * structure, and redraw the string. * * GLOBAL: int hcur_item: * char hcur_text[]: * OBJECT *tree: * * IN: none * OUT: none */ void HDraw() { GRECT rect; sprintf( hcur_text, "%d", hcur_item ); TedText( SLIDEH ) = hcur_text; rect = ObRect( SLIDEH ); objc_offset( tree, SLIDEH, &rect.g_x, &rect.g_y ); objc_draw( tree, SLIDEH, MAX_DEPTH, ELTS( rect ) ); } /* Pop_Handle() *========================================================================== * Setup the strings for the popup menu. We want the strings to have 2 * spaces in front of each string and spaces after the string up to * the length + 1 of the longest string. * * IN: OBJECT *tree: our RCS tree * int button: The popup object we clicked on to get here. * char *items[]: Pointer array to the text for the menu. * int num_items: The number of items in the text array. * int *default_item: The current item to check mark ( zero based) * Set to -1 if no item is to be checked. * int font_size: AES font size - currently the large font * is only supported. * * OUT: # of the menu item selected ( zero based ). * - OR - * -1 No item selected. */ int Pop_Handle( tree, button, items, num_items, default_item, font_size ) OBJECT *tree; int button; char *items[]; int num_items; int *default_item; int font_size; { GRECT butn, world; int i; int obj; butn = ObRect( button ); objc_offset( tree, button, &butn.g_x, &butn.g_y ); world = ObRect( ROOT ); objc_offset( tree, ROOT, &world.g_x, &world.g_y ); /* This will put 2 spaces before each string and 1 space after * each string. For variable length strings, you'll have to * pad spaces up to the length of the longest string plus 1. */ for( i = 0; i < num_items; i++ ) { strcpy( &blanks[i][0], " "); strcat( &blanks[i][0], items[ i ]); strcat( &blanks[i][0], " "); blank[i] = &blanks[i][0]; } obj = (*xcpb->Popup)( blank, num_items, *default_item, font_size, &butn, &world ); return( obj ); }