musicUI.c 3.83 KB

#include <assert.h>

#include "gfx.h"
#include "musicUI.h"
#include "UIpane.h"
#include "UI.h"
#include "transport.h"
#include "sndplayUI.h"
#include "cursor.h"
#include "performance.h"
#include "channelUI.h"


static UIPane *		sPaneList[kNumPanes];
static UIGlobals	sUIGlobals;


static void     __UIPaneInit (int id, UIPane **ppPane);

static void	__UIInitGlobals (void);
static void	__UIDrawGlobals (Gfx **ppGfx);
static void	__UIProcessGlobals (UIEvent *pEvent);
static void	__UIHandleGlobals (UIPane *pPane, UIEvent *pEvent);

static void	__PopPaneToTop (UIPane *pPane);


void
UIInit (void)
{
    int         i;
    
    __UIInitGlobals ();

    for (i=0; i<kNumPanes; i++)
        __UIPaneInit (i, &sPaneList[i]);
}


static void
__UIPaneInit (int id, UIPane **ppPane)
{
    /* Initialize the pane according to its id so we can easily */
    /* debug specific windows by simply altering the ids. */
    /* From here on out pane ids are not used. */
    switch (id)
    {
      case kXptPaneID:
          Xpt_Init (ppPane);
          break;

      case kPerfPaneID:
          Perf_Init (ppPane);
          break;

      case kChlPaneID:
          Chl_Init (ppPane);
          break;

      case kSndPlayID:
	  SndP_Init (ppPane);
	  break;
    }
}


void
UIDraw (Gfx **ppGfx)
{
    UIPane *    pPane;
    int         i;

    /* Draw panes in reverse order so that panes at the top of the list */
    /* appear on top of the other panes. */
    for (i=kNumPanes; --i>=0; )
    {
        pPane = sPaneList[i];
        assert(pPane != NULL);
        
        pPane->DrawProc (pPane, ppGfx);
    }

    /* Draw global UI objects last since they are usually modal. */
    __UIDrawGlobals (ppGfx);
}


void
UIProcessEvent (UIEvent *pEvent)
{
    UIPane *    pPane;
    Point       pt;
    int         i;

     
    /* Handle all global UI events. */
    __UIProcessGlobals (pEvent);

    Crsr_GetCoords (&pt.x, &pt.y);

    /* Send events to panes in forward order so that panes that */
    /* appear on top get to handle events first. */
    for (i=0; i<kNumPanes; i++)
    {
        pPane = sPaneList[i];
        assert(pPane != NULL);
        
        if (PointInRect (&pPane->bounds, &pt))
        {
            if (!pPane->HandleEventProc (pPane, pEvent))
		__UIHandleGlobals (pPane, pEvent);

	    __PopPaneToTop (pPane);

	    break;
        }
    }
}


void
__UIDrawGlobals (Gfx **ppGfx)
{
    Rect moveRect;
    int dx, dy;

    if (sUIGlobals.fMovePane)
    {
	Crsr_GetCoords (&dx, &dy);
	moveRect = sUIGlobals.fMovePane->bounds;
	OffsetRect (&moveRect, dx - sUIGlobals.fMoveOrigin.x, dy - sUIGlobals.fMoveOrigin.y);
	DrawGrayRect (&moveRect, 32, ppGfx);
    }
}
    

void
__UIInitGlobals (void)
{
    int i;
    
    for (i=0; i<kNumPanes; i++)
        sPaneList[i] = NULL;
    
    sUIGlobals.fMovePane = NULL;
}


void
__UIProcessGlobals (UIEvent *pEvent)
{
    int dx, dy;

    if (sUIGlobals.fMovePane && pEvent->type == kMouseUp)
    {
	Crsr_GetCoords (&dx, &dy);
	OffsetRect (&sUIGlobals.fMovePane->bounds, dx - sUIGlobals.fMoveOrigin.x, dy - sUIGlobals.fMoveOrigin.y);
	sUIGlobals.fMovePane = NULL;
    }
}


void
__UIHandleGlobals (UIPane *pPane, UIEvent *pEvent)
{
    if (pEvent->type == kMouseDown)
    {
       assert(sUIGlobals.fMovePane == NULL);

       sUIGlobals.fMovePane = pPane;
       Crsr_GetCoords (&sUIGlobals.fMoveOrigin.x, &sUIGlobals.fMoveOrigin.y);
    }
}


void
__PopPaneToTop (UIPane *pPane)
{
    int i;

    /* Locate 'pPane' in the list. */
    for (i=kNumPanes; --i >= 0; )
    {
	if (sPaneList[i] == pPane)
	    break;
    }

    /* If we didn't find it in the list, then there's a bug somewhere. */
    assert(i>=0);

    /* Shift all panes above 'pPane' down. */
    /* This will do nothing if 'pPane' is already at the top. */
    for (; i > 0; --i)
    {
	sPaneList[i] = sPaneList[i-1];
    }

    /* Place 'pPane' at the top of the list. */
    sPaneList[0] = pPane;
}