Metropoli BBS
VIEWER: wbprogrs.c MODE: TEXT (ASCII)
/***************************************************************************
 *		  Copyright (C) 1995  Charles P. Peterson                  *
 *	     4007 Enchanted Sun, San Antonio, Texas 78244-1254             *
 *              Email: Charles_P_Peterson@fcircus.sat.tx.us                *
 *                                                                         *
 *		  This is free software with NO WARRANTY.                  *
 *	      See gfft.c, or run program itself, for details.              *
 *		      Support is available for a fee.                      *
 ***************************************************************************
 *
 * Program:     gfft--General FFT analysis
 * File:        wbprogrs.c
 * Purpose:     progress requester 
 * Author:      Charles Peterson (CPP)
 * History:     4-Feb-95 (1.31) CPP; Created.
 *              10-Feb-95 (1.36) CPP; Allow interrupt from CLI
 * Comments:    Workbench GUI.  Amiga Dependent!
 *              This may be called from different places for different
 *                progress requesters.
 *              HOWEVER, IT IS NOT RE-ENTRANT.  THERE MUST ONLY BE ONE
 *                ACTIVE PROGRESS REQUESTER AT ANY ONE TIME (in any one
 *                task, anyway).
 */

#ifdef AMIGA  /* This module is AMIGA dependent */

/* #define CHECK_PROGRESS_RATE */

#include <stdio.h>     /* sprintf() */
#include <string.h>    /* strlen() */

/*
 * Amiga includes
 */
#include <exec/types.h>
#include <workbench/workbench.h>
#include <intuition/intuition.h>
#include <clib/intuition_protos.h>
#include <clib/exec_protos.h>
#include <dos.h> /* chkabort() */

/*
 * GFFT includes
 */
#include "gfft.h"
#include "wbench.h"

static struct Window *base_window_p = NULL;
static struct Gadget *static_stop_progress_gadgetp = NULL;
static struct Gadget *static_progress_gadgetp = NULL;

#define STRLEN_STOP 4


struct Requester *progress_requester__new (char *message_text,
					   int min_progress_width)
{
    struct IntuiText *line1_textp;
    struct Gadget *stop_progress_gadgetp = NULL;
    struct Requester *progress_rp = NULL;
    int text_width = strlen (message_text);
    int progress_width;
    int text_indent = 0;
    int stop_indent = 0;

    progress_width = (min_progress_width > text_width) ?
      min_progress_width : text_width;

    if (progress_width < STRLEN_STOP) progress_width = STRLEN_STOP;

    if (progress_width > text_width) text_indent =
      (progress_width - text_width) / 2;

    if (progress_width > STRLEN_STOP) stop_indent =
      (progress_width - STRLEN_STOP) / 2;

    gadget__begin (GTYP_REQGADGET);

    line1_textp = requester_text__new (message_text, text_indent, 0);

    progress_gadget__new (progress_width, 0, 1);

    stop_progress_gadgetp = tall_action_button__new ("STOP", 
						      stop_indent, 3);

    progress_rp = requester__new ();
    progress_rp->ReqGadget = stop_progress_gadgetp;
    progress_rp->ReqText = line1_textp;

    return progress_rp;
}


char *progress_requester__apply (struct Requester *progress_rp,
				 char *command_function(char *command),
				 char *command,
				 struct Window *windowp)
{
    struct IntuiMessage *message;
    char *return_arguments = NULL;
    BOOLEAN error_caught = FALSE;

    if (requester__display (progress_rp, windowp))
    {
	base_window_p = windowp;
	static_stop_progress_gadgetp = progress_rp->ReqGadget;
	static_progress_gadgetp = progress_rp->ReqGadget->NextGadget;
	progress_gadget__clear (static_progress_gadgetp, windowp);
/*
 * Now, execute command, catching errors, if any
 * (stop is raised like an error)
 */
	CATCH_ERROR
	{
	    return_arguments = (*command_function)(command);
	}
	ON_ERROR
	{
	    return_arguments = NULL;
	    error_caught = TRUE;
	}
	END_CATCH_ERROR;

	while (message = (struct IntuiMessage *) GetMsg 
	       (base_window_p->UserPort))
	{
	    ReplyMsg ((struct Message *) message);
	}
	requester__remove (progress_rp, base_window_p);

	base_window_p = NULL;

	if (error_caught)
	{
	    RAISE_ERROR (NOTHING_SPECIAL);
	}
    }
    else  /* Couldn't display requester.  Probably memory error. */
    {
	error_message (OUT_OF_MEMORY);
	RAISE_ERROR (NOTHING_SPECIAL);
    }
    return return_arguments;
}

void progress_requester__update (int percent_done)
{
    progress_requester__check_stop ();

    if (base_window_p)
    {
	progress_gadget__update (static_progress_gadgetp, percent_done, 
				 base_window_p);
    }
    return;
}

void progress_requester__check_stop (void)
{
    struct IntuiMessage *message;
    APTR *address = NULL;

#ifdef CHECK_PROGRESS_RATE
    static int i = 0;
    printf ("Stop test: %d\n", ++i);
#endif

    if (!base_window_p)   /* progress requester not active */
    {
	chkabort();
	if (Interrupt_Count)
	{
	    printf ("\n***BREAK\n");
	    RAISE_ERROR (NOTHING_SPECIAL);
	}
	return;
    }

    while (message = (struct IntuiMessage *) GetMsg 
	   (base_window_p->UserPort))
    {
	address = message->IAddress;
	ReplyMsg ((struct Message *) message);
	if (address == (APTR) static_stop_progress_gadgetp)
	{
	    RAISE_ERROR (NOTHING_SPECIAL);
	}
    }
}

#endif /* end ifdef AMIGA */
[ RETURN TO DIRECTORY ]