/***********************************************************************
 *
 *	Copyright (c) Geoworks 1993 -- All Rights Reserved
 *
 * PROJECT:	  C Sample Applications
 * MODULE:	  HelpSamp sample application for GEOS help system.
 * FILE:	  helpsamp.goc
 *
 * AUTHOR:  	  Peter Dudley, 22 January 1993
 *
 * REVISION HISTORY:
 *		Date	Name	Description
 *		----	----	-----------
 *		2/ 3	PjD	Initial Version
 *
 * DESCRIPTION:
 *	Sample C file for showing how to use help in a C application.
 *	This file contains the entire application, including object
 *	trees and class code.
 *
 *	$Id: helpsamp.goc,v 1.1.11.2 93/10/13 23:30:35 joon Exp $
 *
 ***********************************************************************/
/**************************************************************************
 *		Include files
 **************************************************************************/

@include <stdapp.goh>

/**************************************************************************
 *		Class & Message Definitions
 **************************************************************************/

	/*
	 * The three messages defined for HelpSampProcessClass are
	 * MSG_HELPSAMP_SET_HELP_FILE
	 *	Retrieves the selection in the file list and sets the
	 *	GenApplication's help file accordingly.
	 * MSG_HELPSAMP_SET_AND_DISPLAY
	 *	Retrieves the selection in the file list and sets the
	 *	GenApplication's help file accordingly, then brings up
	 *	the help screen for it.
	 * MSG_HELPSAMP_SET_TYPE
	 *	Retrieves the selection in the type list and sets the
	 *	GenApplication's help type accordingly.
	 */
@class	HelpSampProcessClass, GenProcessClass;
    @message void MSG_HELPSAMP_SET_HELP_FILE();
    @message void MSG_HELPSAMP_SET_AND_DISPLAY();
    @message void MSG_HELPSAMP_SET_TYPE();
@endc

@classdecl	HelpSampProcessClass, neverSaved;

/**************************************************************************
 *		UI Objects
 **************************************************************************/

@start	AppResource;

/*
 * For all types of help other than Normal Help, you must
 * provide a help control object for it.  Almost always,
 * the help controllers are children of the GenApplication,
 * as in this application.  This application offers Normal Help
 * by default, First Aid help through FirstAidHelpControl, and
 * Simple Help through SimpleHelpControl.
 *     The helpcontrol objects you define must be on two different
 * GCN lists, as shown in the definition below.  They must each be
 * on the GAGCNLT_NOTIFY_HELP_CONTEXT_CHANGE list, which notifies
 * all help controllers that a context change has occurred.  They
 * must also be on the MGCNLT_ACTIVE_LIST because they are subclassed
 * from GenControl, and all controllers must be on the active list.
 */
@object GenApplicationClass HelpSampApp = {
    GI_visMoniker = list { @HelpSampTextMoniker };
    GI_comp = @HelpSampPrimary, @FirstAidHelpControl, @SimpleHelpControl;
    gcnList(MANUFACTURER_ID_GEOWORKS,GAGCNLT_WINDOWS) = @HelpSampPrimary;
    gcnList(MANUFACTURER_ID_GEOWORKS, GAGCNLT_NOTIFY_HELP_CONTEXT_CHANGE) =
							@FirstAidHelpControl,
							@SimpleHelpControl;
    gcnList(MANUFACTURER_ID_GEOWORKS, MGCNLT_ACTIVE_LIST) =
							@FirstAidHelpControl,
							@SimpleHelpControl;
}

@visMoniker HelpSampTextMoniker = "C Sample App with Help";

@end	AppResource


/*
 *     The HelpControlResource resource contains all of our own help
 * controller objects.  They don't have to be placed in their own
 * resource.
 */
@start	HelpControlResource;

/*     Each help controller controls one type of help.  The type of help
 * actually used at any given time depends on the type assigned to
 * the GenApplication object with ATTR_GEN_HELP_TYPE.  If that attribute
 * is not applied, Normal Help is used.
 *    The HCI_helpType instance field defines the type of help managed
 * by the controller.  These are values of the HelpType enumerated type.
 * Because the default behavior is for a help window to be on top of all
 * other dialog boxes, the window priority of each controller is set to
 * WIN_PRIO_ON_TOP.  The effect is to layer the windows according to their
 * places in the GenApplication's child list.
 *    Both controllers are set GS_ENABLED because the default GenControl
 * action is to disable its UI until told to enable it.
 */
@object HelpControlClass FirstAidHelpControl = {
    GI_states = @default | GS_ENABLED;
    HCI_helpType = HT_FIRST_AID;
    ATTR_GEN_WINDOW_CUSTOM_WINDOW_PRIORITY = (WIN_PRIO_ON_TOP);
}

@object HelpControlClass SimpleHelpControl = {
    GI_states = @default | GS_ENABLED;
    HCI_helpType = HT_SIMPLE_HELP;
    ATTR_GEN_WINDOW_CUSTOM_WINDOW_PRIORITY = (WIN_PRIO_ON_TOP);
}

@end	HelpControlResource


@start	Interface;

/*     HelpSampPrimary has a single menu child and a single organizational
 * GenInteraction child.  It has the help context "TOC," which will create
 * the primary's help trigger (placed in the title bar) and will bring up
 * the TOC context of the help file specified by the GenApplication.
 */
@object GenPrimaryClass HelpSampPrimary  = {
    GI_comp = @ChangeMenu, @StatusBox;
    HINT_PRIMARY_FULL_SCREEN;
    ATTR_GEN_HELP_CONTEXT = "TOC";
}

/* --------------------------------------------------------------------------*/
/*     The StatusBox GenInteraction is used only to display which help file
 * and which help type are currently active and affected by the help triggers.
 * Because the change dialog boxes have "Apply" triggers, it can be
 * confusing when the selection in the dialog box does not accurately reflect
 * the help conditions; these status glyphs are provided to show what the
 * GenApplication is actually doing.
 *     The glyphs that reflect the help state have three different monikers,
 * one for each option.  When the user changes either the file or the type,
 * a message is sent to the glyph to have it change its moniker appropriately.
 */
@object GenInteractionClass StatusBox = {
    GI_comp = @FileBox, @TypeBox;
    HINT_ORIENT_CHILDREN_VERTICALLY;
    HINT_FULL_JUSTIFY_CHILDREN_HORIZONTALLY;
}

@object GenInteractionClass FileBox = {
    GI_visMoniker = "Current Help File";
    GI_comp = @FileGlyph;
    HINT_DRAW_IN_BOX;
    HINT_PLACE_MONIKER_ABOVE;
    HINT_CENTER_MONIKER;
    HINT_EXPAND_WIDTH_TO_FIT_PARENT;
}

@object GenGlyphClass FileGlyph = {
    GI_visMoniker = list { @DefFileMon }
}

@visMoniker DefFileMon = "Default Help File";
@visMoniker BoxFileMon = "Help File with Boxes";
@visMoniker CirFileMon = "Help File with Circles";


@object GenInteractionClass TypeBox = {
    GI_visMoniker = "Current Help Type";
    GI_comp = @TypeGlyph;
    HINT_DRAW_IN_BOX;
    HINT_PLACE_MONIKER_ABOVE;
    HINT_CENTER_MONIKER;
    HINT_EXPAND_WIDTH_TO_FIT_PARENT;
}

@object GenGlyphClass TypeGlyph = {
    GI_visMoniker = list { @NorHelpMon }
}

@visMoniker NorHelpMon = "Normal Help";
@visMoniker FirstAidMon = "First Aid Help";
@visMoniker SimHelpMon = "Simple Help";


/* --------------------------------------------------------------------------*/

/*     The ChangeMenu has two dialog box children, one to change the
 * GenApplication's help file and one to change the GenApplication's help
 * type.  The ChangeMenu has the help context "Help Files," which will
 * cause the "Help Files" context from the current help file to be
 * displayed when the F1 key is hit and the menu has the focus.
 */
@object GenInteractionClass ChangeMenu = {
	GI_visMoniker = 'C', "Change";
	GI_comp = @ChangeDialog, @TypeDialog;
	GII_visibility = GIV_POPUP;
	ATTR_GEN_HELP_CONTEXT = "Help Files";
}

/*     The ChangeDialog dialog box allows the user to change the help
 * file currently being used by the application.  It has a GenItemGroup
 * listing three options:  Default file, a file with graphic boxes, and
 * a file with graphic circles.
 *     The reply bar has two "Apply" triggers--one that merely changes
 * the file, and one that also displays the new help file immediately--
 * as well as a "Cancel" trigger and its own help trigger.
 *     Because this application uses only one help file at a time
 * (individual objects do not use their own files), the GenApplication
 * controls which file is used.  It does this with ATTR_GEN_HELP_FILE.
 * If this attribute is not applied, the default file (helpsamp) will
 * be used.  If the attribute is applied, the file named therein will
 * be used.  The current help file is managed by manipulating this attribute.
 *     The ChangeDialog dialog box has the same help context as the
 * Change menu.
 */
@object GenInteractionClass ChangeDialog = {
	GI_visMoniker = 'C', "Change Help File";
	GI_comp = @ChangeList, @ChangeTrig, @ChangeAndApplyTrig, @CancelTrig;
	GII_visibility = GIV_DIALOG;
	GII_type = GIT_MULTIPLE_RESPONSE;
	HINT_ORIENT_CHILDREN_VERTICALLY;
	ATTR_GEN_HELP_CONTEXT = "Help Files";
}

/* The ChangeList does not have its own help context for one reason:
 * it would never be used.  If the user clicks a help trigger, the
 * context of the help trigger is used.  If the user hits the F1 key
 * to get help on the current focus object (the list), it will actually
 * display the help screen of the list entry (a GenItem).  This is
 * because it takes the current focus and searches up the generic tree
 * until it finds a help context; since each list entry has its own
 * context, the list's context would never be invoked.
 */
@object	GenItemGroupClass ChangeList = {
	GI_comp = @DefaultFile, @BoxFile, @CircFile;
	GIGI_numSelections = 1;
	GIGI_selection = 1;
	HINT_ORIENT_CHILDREN_VERTICALLY;
}

@object GenItemClass DefaultFile = {
	GI_visMoniker = "Use Default Help File";
	GII_identifier = 1;
	ATTR_GEN_HELP_CONTEXT = "Default File";
}

@object GenItemClass BoxFile = {
	GI_visMoniker = "Use Help File with Squares";
	GII_identifier = 2;
	ATTR_GEN_HELP_CONTEXT = "Box File";
}

@object GenItemClass CircFile = {
	GI_visMoniker = "Use Help File with Circles";
	GII_identifier = 3;
	ATTR_GEN_HELP_CONTEXT = "Circle File";
}

/*     The ChangeTrig sends MSG_HELPSAMP_SET_HELP_FILE to the
 * process object.  This message will set ATTR_GEN_HELP_FILE
 * correctly but will not dynamically update the help window.
 */
@object GenTriggerClass ChangeTrig = {
	GI_visMoniker = "Change File";
	GTI_destination = process;
	GTI_actionMsg = MSG_HELPSAMP_SET_HELP_FILE;
	HINT_SEEK_REPLY_BAR;
}

/*     The ChangeAndApplyTrig sends MSG_HELPSAMP_SET_AND_DISPLAY to
 * the process object.  This message will set ATTR_GEN_HELP_FILE
 * correctly and will dynamically update the help window.
 */
@object GenTriggerClass ChangeAndApplyTrig = {
	GI_visMoniker = "Change File and Display";
	GTI_destination = process;
	GTI_actionMsg = MSG_HELPSAMP_SET_AND_DISPLAY;
	HINT_SEEK_REPLY_BAR;
}

/*     The CancelTrig trigger closes the GenInteraction without applying
 * any changes.  */
@object GenTriggerClass CancelTrig = {
	GI_visMoniker = "Cancel";
	ATTR_GEN_TRIGGER_INTERACTION_COMMAND = (IC_DISMISS);
	HINT_SEEK_REPLY_BAR;
}

/*     The TypeDialog allows the user to change the help type currently
 * being used by the application.  It is a much simpler dialog than the
 * help file dialog in that it simply changes the help type without offering
 * the option of dynamically updating the help window(s).
 *     The help context of the TypeDialog is "Help Types."  When help is
 * invoked, this help context describes help types to the user.  Each entry
 * in the type list in the dialog box also has its own context and help
 * screen.
 */

@object GenInteractionClass TypeDialog = {
	GI_visMoniker = 'T', "Change Help Type";
	GI_comp = @TypeList;
	GII_visibility = GIV_DIALOG;
	GII_type = GIT_PROPERTIES;
	ATTR_GEN_HELP_CONTEXT = "Help Types";
}

@object GenItemGroupClass TypeList = {
	GI_comp = @NormalItem, @FirstAidItem, @SimpleItem;
	GIGI_numSelections = 1;
	GIGI_selection = HT_NORMAL_HELP;
	GIGI_applyMsg = MSG_HELPSAMP_SET_TYPE;
	GIGI_destination = process;
	HINT_ORIENT_CHILDREN_VERTICALLY;
}

@object GenItemClass NormalItem = {
	GI_visMoniker = "Normal Help";
	GII_identifier = HT_NORMAL_HELP;
	ATTR_GEN_HELP_CONTEXT = "Normal Help";
}

@object GenItemClass FirstAidItem = {
	GI_visMoniker = "First Aid";
	GII_identifier = HT_FIRST_AID;
	ATTR_GEN_HELP_CONTEXT = "First Aid";
}

@object GenItemClass SimpleItem = {
	GI_visMoniker = "Simple Help";
	GII_identifier = HT_SIMPLE_HELP;
	ATTR_GEN_HELP_CONTEXT = "Simple Help";
}

@end Interface

/* --------------------------------------------------------------------------*/

/**************************************************************************
 *
 *		Methods for HelpSampProcessClass
 *
 **************************************************************************/


/**************************************************************************
 * 	MSG_HELPSAMP_SET_HELP_FILE for HelpSampProcessClass
 **************************************************************************
 * SYNOPSIS:		Gets the new file from the change file dialog
 *			box and sets ATTR_GEN_HELP_FILE in the
 *			GenApplication object.
 * PARAMETERS:		void ();
 * SIDE EFFECTS:	Status glyph updated.
 *
 * STRATEGY:		Retrieve the selection from ChangeList and
 *			set ATTR_GEN_HELP_FILE appropriately, updating
 *			the status glyph.
 *
 *************************************************************************/
@method HelpSampProcessClass, MSG_HELPSAMP_SET_HELP_FILE {
    word	curSel;
    char	BoxHelpFile[] = "squares";
    char	CircHelpFile[] = "circles";

    curSel = @call ChangeList::MSG_GEN_ITEM_GROUP_GET_SELECTION();
    if (curSel == 1) {
	(void) @call HelpSampApp::MSG_META_DELETE_VAR_DATA(ATTR_GEN_HELP_FILE);
	(void) @call FileGlyph::MSG_GEN_REPLACE_VIS_MONIKER_OPTR(
					@DefFileMon, VUM_NOW);
    } else if (curSel == 2) {
	@call HelpSampApp::MSG_META_SET_HELP_FILE(BoxHelpFile);
	(void) @call FileGlyph::MSG_GEN_REPLACE_VIS_MONIKER_OPTR(
					@BoxFileMon, VUM_NOW);
    } else if (curSel == 3) {
	@call HelpSampApp::MSG_META_SET_HELP_FILE(CircHelpFile);
	(void) @call FileGlyph::MSG_GEN_REPLACE_VIS_MONIKER_OPTR(
					@CirFileMon, VUM_NOW);
    }
}


/**************************************************************************
 * 	MSG_HELPSAMP_SET_AND_DISPLAY for HelpSampProcessClass
 **************************************************************************
 * SYNOPSIS:		Gets the new file from the change file dialog
 *			box and sets ATTR_GEN_HELP_FILE in the
 *			GenApplication object.  Then it invokes the
 *			help on the new help file.
 * PARAMETERS:		void ();
 * SIDE EFFECTS:	Status glyph updated.
 *
 * STRATEGY:		Call MSG_HELPSAMP_SET_HELP_FILE and then
 *			MSG_META_BRING_UP_HELP.
 *
 *************************************************************************/
@method HelpSampProcessClass, MSG_HELPSAMP_SET_AND_DISPLAY {
    @call self::MSG_HELPSAMP_SET_HELP_FILE();
    @call HelpSampPrimary::MSG_META_BRING_UP_HELP();
}


/**************************************************************************
 * 	MSG_HELPSAMP_SET_TYPE for HelpSampProcessClass
 **************************************************************************
 * SYNOPSIS:		Gets the new type from the change type dialog
 *			box and sets ATTR_GEN_HELP_TYPE in the
 *			GenApplication object.
 * PARAMETERS:		void ();
 * SIDE EFFECTS:	Status glyph updated.
 *
 * STRATEGY:		Retrieve the selection from TypeList and
 *			set ATTR_GEN_HELP_TYPE appropriately, updating
 *			the status glyph.
 *
 *************************************************************************/
@method HelpSampProcessClass, MSG_HELPSAMP_SET_TYPE {
    word	curSel;

    curSel = @call TypeList::MSG_GEN_ITEM_GROUP_GET_SELECTION();
    (void) @call HelpSampApp::MSG_META_DELETE_VAR_DATA(ATTR_GEN_HELP_TYPE);
    if (curSel == HT_NORMAL_HELP) {
	(void) @call TypeGlyph::MSG_GEN_REPLACE_VIS_MONIKER_OPTR(
						@NorHelpMon, VUM_NOW);
    } else if (curSel == HT_FIRST_AID) {
	(void) @call TypeGlyph::MSG_GEN_REPLACE_VIS_MONIKER_OPTR(
						@FirstAidMon, VUM_NOW);
	(void) @call HelpSampApp::MSG_META_ADD_VAR_DATA(ATTR_GEN_HELP_TYPE,
						sizeof(HelpType), &curSel);
    } else if (curSel == HT_SIMPLE_HELP) {
	(void) @call TypeGlyph::MSG_GEN_REPLACE_VIS_MONIKER_OPTR(
						@SimHelpMon, VUM_NOW);
	(void) @call HelpSampApp::MSG_META_ADD_VAR_DATA(ATTR_GEN_HELP_TYPE,
						sizeof(HelpType), &curSel);
    }
}
