Contents page

Rules for Tools/Tool Structure

The Tool Structure When Bars&Pipes creates a Tool and plops it in a PipeLine, that instance of the Tool is defined by a separate structure, the Tool structure. This carries all of the information that is needed for this particular use of the Tool. When the `edittool()' and `processevent()' routines are called, they work with this Tool. Each Tool is composed of a kernel structure, the Tool structure, and any fields you might tag onto the end for your particular Tool design. For example, a delay tool has a field that determines by how many clock ticks to delay MIDI events. Here's the Tool structure, as defined in `bars.h':

struct Tool {
    struct Tool *next;          /* Next tool used in Track. */
    struct Tool *branch;        /* Tool on other Track. */
    struct Tool *parent;        /* Parent tool (for macros.) */
    struct ToolMaster *toolmaster;/* ToolMaster. */
    struct Clip *clip;          /* Clip to be worked on. */
    struct String *name;        /* Name of this tool. */
    struct Window *window;      /* Edit window. */
    struct Track *track;        /* Track that owns this tool. */
    long toolid;                /* Tool ID. */
    unsigned short left,top;    /* Position of edit window. */
    unsigned short width,height;/* Size of edit window. */
    unsigned short x,y;         /* Position in pipe display. */
    unsigned short xindex;      /* How far down list this is. */
    unsigned short yindex;      /* How far down track list. */
    short branchindex;          /* How far away branch tool is. */
    unsigned short id;          /* ID for file io. */
    char intool;                /* True if in left PipeLine. */
    char inedit;                /* Indicates editing now. */
    char touched;               /* Initialization bits. */
    char selected;              /* Icon selected in graph? */
    long tooltype;              /* Sequence? Input? Branch? */ };

   Here's an example Delay Tool that nests the Tool structure within it:

struct DelayTool {
    struct Tool tool;       /* Tool stuff. */
    long delaytime;         /* Delay time. */ 

   Because the standard Tool structure  is nested within DelayTool, Bars&Pipes can
access everything it needs to know about the Delay Tool, yet the Delay Tool can store
its additional information, the delay time,  in the very same structure.

   Here are definitions of the important Tool structure fields:

     A pointer to the Tool that follows this Tool is placed in the
     `next' field.  This is the linkage that ties each PipeLine
     together.  When a Tool is finished processing an Event, it must
     place the pointer to the next Tool in the Event so the Event can
     be passed on properly.

     If the Tool is capable of sending Events to a Tool on another
     PipeLine (Events sent to another pipeline are always sent to a
     Merge In Tool,) `branch' holds a pointer to that Tool.  Routing an
     Event to the branching Tool is accomplished by placing that Tool,
     rather than the next Tool in the PipeLine, into the Event

     To access all of the generic information about a Tool, including
     its name, image, and various routines, a pointer to the ToolMaster
     structure that defines the Tool is stored in `toolmaster'.

     This is the Clip the Tool is currently working on.  Although Tools
     rarely touch the list of Events within the Clip,  they may need to
     refer to Song Parameters in the Clip. (For example, the Transpose
     Tool  uses the Key&Scale/Mode of the Clip to determine how  to
     tranpose a note within the Key.)

     When a Tool is first created, all of the special data fields that
     you have defined (for example, the delay in clocks for a delay
     Tool) are blank.  At this point, touched is also blank.  Two bits,
     `TOUCH_EDIT' and `TOUCH_INIT' are set in `touched' once the data
     fields are set, either by the user editing the Tool or by the Tool
     itself when the first Event enters it.  In the latter case, the
     Tool always checks if either bit is set when an Event arrives to
     see if the data fields are initialized.  If they aren't, it does
     the initialization and sets the `TOUCH_INIT' bit. See
     Tool Touched Flags.