773 lines
21 KiB
C
773 lines
21 KiB
C
/******************************************************************************
|
||
*
|
||
* File: MainForm.c
|
||
*
|
||
* Project : Example 7
|
||
*
|
||
*****************************************************************************/
|
||
|
||
#include <PalmOS.h>
|
||
#include <vfsmgr.h>
|
||
#include "StarterRsc.h"
|
||
|
||
#include "Vga.h"
|
||
#include "Audio.h"
|
||
#include "TrgChars.h"
|
||
#include "Wave.h"
|
||
#include "starter.h"
|
||
#include "MainForm.h"
|
||
|
||
/***********************************************************************
|
||
*
|
||
* Local Types
|
||
*
|
||
***********************************************************************/
|
||
typedef enum {
|
||
audioStateNoVolume,
|
||
audioStateNoFile,
|
||
audioStateOpen,
|
||
audioStatePlaying,
|
||
audioStateRecording
|
||
} AudioStateType;
|
||
|
||
/***********************************************************************
|
||
*
|
||
* Global variables
|
||
*
|
||
***********************************************************************/
|
||
extern Boolean vgaPresent;
|
||
extern Boolean auxButtonPresent;
|
||
extern Boolean cardChangedOccurred;
|
||
|
||
/***********************************************************************
|
||
*
|
||
* Local Constants
|
||
*
|
||
***********************************************************************/
|
||
#define WAVE_FILE "ExampleJ.wav"
|
||
|
||
#define recordStartEvent ((eventsEnum)((Int16)firstUserEvent))
|
||
|
||
/***********************************************************************
|
||
*
|
||
* Local Functions
|
||
*
|
||
***********************************************************************/
|
||
static void *GetObjectPtr (UInt16 objectID);
|
||
static void SetControls (void);
|
||
static void SetSliderPercent (FormPtr frmP, UInt16 percent);
|
||
static void HideObject (UInt16 id);
|
||
static void ShowObject (UInt16 id);
|
||
|
||
static void HandlePlayButton (void);
|
||
static void HandleStopButton (void);
|
||
static void HandleRecordButton (void);
|
||
static void HandleProgress (EventPtr eventP);
|
||
static void HandlePauseButton (void);
|
||
static void HandleSliderControl(EventPtr eventP);
|
||
|
||
|
||
/***********************************************************************
|
||
*
|
||
* Local Variables
|
||
*
|
||
***********************************************************************/
|
||
static AudioStateType audioState;
|
||
static Boolean canRecord;
|
||
static Boolean launchedFromButton;
|
||
|
||
|
||
/***********************************************************************
|
||
*
|
||
* FUNCTION: GetObjectPtr
|
||
*
|
||
* DESCRIPTION: This routine returns a pointer to an object in the current
|
||
* form.
|
||
*
|
||
* PARAMETERS: formId - id of the form to display
|
||
*
|
||
* RETURNED: void *
|
||
*
|
||
***********************************************************************/
|
||
static void * GetObjectPtr(UInt16 objectID)
|
||
{
|
||
FormPtr frmP;
|
||
|
||
frmP = FrmGetActiveForm();
|
||
return(FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, objectID)));
|
||
}
|
||
|
||
|
||
/***********************************************************************
|
||
*
|
||
* FUNCTION: PrvMoveObject
|
||
*
|
||
* DESCRIPTION: This routine moves an object vertically within a form.
|
||
*
|
||
* PARAMETERS:
|
||
*
|
||
* RETURNED: nothing
|
||
*
|
||
***********************************************************************/
|
||
static void PrvMoveObject(FormPtr frmP, UInt16 objIndex, Coord y_diff, Boolean draw)
|
||
{
|
||
RectangleType r;
|
||
|
||
FrmGetObjectBounds(frmP, objIndex, &r);
|
||
if (draw)
|
||
{
|
||
RctInsetRectangle(&r, -2); //need to erase the frame as well
|
||
WinEraseRectangle(&r, 0);
|
||
RctInsetRectangle(&r, 2);
|
||
}
|
||
r.topLeft.y += y_diff;
|
||
FrmSetObjectBounds(frmP, objIndex, &r);
|
||
}
|
||
|
||
|
||
/***********************************************************************
|
||
*
|
||
* FUNCTION: SetSliderPercent
|
||
*
|
||
* DESCRIPTION:
|
||
*
|
||
* PARAMETERS:
|
||
*
|
||
* RETURNED: Nothing
|
||
*
|
||
***********************************************************************/
|
||
static void SetSliderPercent(FormPtr frmP, UInt16 percent)
|
||
{
|
||
ControlPtr sliderP;
|
||
|
||
sliderP = (ControlPtr)GetObjectPtr(MainProgressSliderControl);
|
||
CtlSetSliderValues(sliderP, NULL, NULL, NULL, &percent);
|
||
}
|
||
|
||
/***********************************************************************
|
||
*
|
||
* FUNCTION: HideObject
|
||
*
|
||
* DESCRIPTION:
|
||
*
|
||
* PARAMETERS:
|
||
*
|
||
* RETURNED: Nothing
|
||
*
|
||
***********************************************************************/
|
||
static void HideObject(UInt16 id)
|
||
{
|
||
UInt16 obj_index;
|
||
|
||
obj_index = FrmGetObjectIndex(FrmGetActiveForm(), id);
|
||
FrmHideObject(FrmGetActiveForm(), obj_index);
|
||
}
|
||
|
||
/***********************************************************************
|
||
*
|
||
* FUNCTION: ShowObject
|
||
*
|
||
* DESCRIPTION:
|
||
*
|
||
* PARAMETERS:
|
||
*
|
||
* RETURNED: Nothing
|
||
*
|
||
***********************************************************************/
|
||
static void ShowObject(UInt16 id)
|
||
{
|
||
UInt16 obj_index;
|
||
|
||
obj_index = FrmGetObjectIndex(FrmGetActiveForm(), id);
|
||
FrmShowObject(FrmGetActiveForm(), obj_index);
|
||
}
|
||
|
||
|
||
/***********************************************************************
|
||
*
|
||
* FUNCTION: SetControls
|
||
*
|
||
* DESCRIPTION:
|
||
*
|
||
* PARAMETERS:
|
||
*
|
||
* RETURNED: Nothing
|
||
*
|
||
***********************************************************************/
|
||
static void SetControls(void)
|
||
{
|
||
FieldPtr fldP;
|
||
Char *tmp;
|
||
FormPtr frmP;
|
||
|
||
switch (audioState)
|
||
{
|
||
case audioStateNoVolume :
|
||
HideObject(MainPlayButton);
|
||
HideObject(MainPauseButton);
|
||
HideObject(MainRecordButton);
|
||
HideObject(MainStopButton);
|
||
HideObject(MainProgressSliderControl);
|
||
ShowObject(MainCardNotFoundLabel);
|
||
HideObject(MainProgressField);
|
||
break;
|
||
case audioStateNoFile :
|
||
HideObject(MainPlayButton);
|
||
HideObject(MainPauseButton);
|
||
canRecord ? ShowObject(MainRecordButton) : HideObject(MainRecordButton);
|
||
HideObject(MainStopButton);
|
||
HideObject(MainProgressSliderControl);
|
||
HideObject(MainCardNotFoundLabel);
|
||
HideObject(MainProgressField);
|
||
break;
|
||
case audioStateOpen :
|
||
ShowObject(MainPlayButton);
|
||
ShowObject(MainPauseButton);
|
||
canRecord ? ShowObject(MainRecordButton) : HideObject(MainRecordButton);
|
||
ShowObject(MainStopButton);
|
||
ShowObject(MainProgressSliderControl);
|
||
HideObject(MainCardNotFoundLabel);
|
||
HideObject(MainProgressField);
|
||
break;
|
||
case audioStatePlaying :
|
||
HideObject(MainPlayButton);
|
||
ShowObject(MainPauseButton);
|
||
HideObject(MainRecordButton);
|
||
ShowObject(MainStopButton);
|
||
ShowObject(MainProgressSliderControl);
|
||
HideObject(MainCardNotFoundLabel);
|
||
HideObject(MainProgressField);
|
||
break;
|
||
case audioStateRecording :
|
||
HideObject(MainPlayButton);
|
||
HideObject(MainPauseButton);
|
||
HideObject(MainRecordButton);
|
||
ShowObject(MainStopButton);
|
||
HideObject(MainProgressSliderControl);
|
||
HideObject(MainCardNotFoundLabel);
|
||
frmP = FrmGetActiveForm();
|
||
ShowObject(MainProgressField);
|
||
fldP = (FieldPtr)GetObjectPtr(MainProgressField);
|
||
if ((tmp = FldGetTextPtr(fldP)) != NULL)
|
||
MemPtrFree(tmp);
|
||
tmp = (Char *)MemPtrNew(10);
|
||
StrCopy(tmp, "00:00");
|
||
FldSetTextPtr(fldP, tmp);
|
||
FldDrawField(fldP);
|
||
break;
|
||
}
|
||
}
|
||
|
||
/***********************************************************************
|
||
*
|
||
* FUNCTION: HandlePlayButton
|
||
*
|
||
* DESCRIPTION:
|
||
*
|
||
* PARAMETERS:
|
||
*
|
||
* RETURNED: Nothing
|
||
*
|
||
***********************************************************************/
|
||
static void HandlePlayButton(void)
|
||
{
|
||
Err retval;
|
||
|
||
if (audioState != audioStateOpen)
|
||
return;
|
||
|
||
audioState = audioStatePlaying;
|
||
SetControls();
|
||
if ((retval = WavePlay()) == errNone)
|
||
audioState = audioStateOpen;
|
||
SetControls();
|
||
|
||
if (retval != errNone)
|
||
ErrAlert(retval);
|
||
}
|
||
|
||
/***********************************************************************
|
||
*
|
||
* FUNCTION: HandlePauseButton
|
||
*
|
||
* DESCRIPTION:
|
||
*
|
||
* PARAMETERS:
|
||
*
|
||
* RETURNED: Nothing
|
||
*
|
||
***********************************************************************/
|
||
static void HandlePauseButton(void)
|
||
{
|
||
if (audioState != audioStatePlaying)
|
||
return;
|
||
|
||
/*------------------------------------------------------------------------
|
||
* Note : There is no pause state. WavePlay() will return after call to
|
||
* WavePause(), which will put state into audioStateStop.
|
||
*----------------------------------------------------------------------*/
|
||
WavePause();
|
||
}
|
||
|
||
/***********************************************************************
|
||
*
|
||
* FUNCTION: HandleStopButton
|
||
*
|
||
* DESCRIPTION:
|
||
*
|
||
* PARAMETERS:
|
||
*
|
||
* RETURNED: Nothing
|
||
*
|
||
***********************************************************************/
|
||
static void HandleStopButton(void)
|
||
{
|
||
WaveStop();
|
||
SetSliderPercent(FrmGetActiveForm(), 0);
|
||
}
|
||
|
||
/***********************************************************************
|
||
*
|
||
* FUNCTION: HandleRecordButton
|
||
*
|
||
* DESCRIPTION:
|
||
*
|
||
* PARAMETERS:
|
||
*
|
||
* RETURNED: Nothing
|
||
*
|
||
***********************************************************************/
|
||
static void HandleRecordButton(void)
|
||
{
|
||
Boolean savedLaunchedFlag = false;
|
||
Err retval;
|
||
|
||
if (audioState == audioStatePlaying)
|
||
return;
|
||
|
||
WaveClose();
|
||
|
||
if ((retval = WaveCreate(WAVE_FILE)) == errNone)
|
||
{
|
||
audioState = audioStateRecording;
|
||
SetControls();
|
||
|
||
if (launchedFromButton)
|
||
{
|
||
savedLaunchedFlag = true;
|
||
SndPlaySystemSound(sndInfo);
|
||
SysTaskDelay(8);
|
||
}
|
||
|
||
retval = WaveRecord();
|
||
|
||
if (savedLaunchedFlag)
|
||
{
|
||
SndPlaySystemSound(sndInfo);
|
||
SysTaskDelay(10);
|
||
SndPlaySystemSound(sndInfo);
|
||
}
|
||
|
||
WaveClose();
|
||
|
||
if (retval == errNone)
|
||
{
|
||
if (WaveOpen(WAVE_FILE) == errNone)
|
||
{
|
||
audioState = audioStateOpen;
|
||
SetSliderPercent(FrmGetActiveForm(), 0);
|
||
}
|
||
else
|
||
audioState = audioStateNoFile;
|
||
}
|
||
}
|
||
else
|
||
audioState = audioStateNoFile;
|
||
|
||
if (retval != errNone)
|
||
ErrAlert(retval);
|
||
|
||
SetSliderPercent(FrmGetActiveForm(), 0);
|
||
SetControls();
|
||
}
|
||
|
||
/***********************************************************************
|
||
*
|
||
* FUNCTION: HandleProgress
|
||
*
|
||
* DESCRIPTION:
|
||
*
|
||
* PARAMETERS:
|
||
*
|
||
* RETURNED: Nothing
|
||
*
|
||
***********************************************************************/
|
||
static void HandleProgress(EventPtr eventP)
|
||
{
|
||
FormPtr frmP;
|
||
FieldPtr fldP;
|
||
UInt8 percent;
|
||
UInt16 minutes, seconds;
|
||
|
||
percent = eventP->tapCount;
|
||
minutes = eventP->screenX;
|
||
seconds = eventP->screenY;
|
||
|
||
frmP = FrmGetActiveForm();
|
||
|
||
if (launchedFromButton)
|
||
{
|
||
/*------------------------------------------------------------------------
|
||
* If user let go of the Aux button
|
||
*----------------------------------------------------------------------*/
|
||
if (auxButtonPresent && ((KeyCurrentState() & keyBitAux) == 0))
|
||
{
|
||
launchedFromButton = false;
|
||
WaveStop();
|
||
SetSliderPercent(FrmGetActiveForm(), 0);
|
||
return;
|
||
}
|
||
}
|
||
|
||
if (audioState == audioStatePlaying)
|
||
SetSliderPercent(frmP, percent);
|
||
else if (audioState == audioStateRecording)
|
||
{
|
||
Char *buf, *tmp;
|
||
|
||
buf = (Char *)MemPtrNew(20);
|
||
StrPrintF(buf, "%02d:%02d", minutes, seconds);
|
||
fldP = (FieldPtr)GetObjectPtr(MainProgressField);
|
||
if ((tmp = FldGetTextPtr(fldP)) != NULL)
|
||
MemPtrFree(tmp);
|
||
FldSetTextPtr(fldP, buf);
|
||
FldDrawField(fldP);
|
||
}
|
||
|
||
EvtResetAutoOffTimer();
|
||
}
|
||
|
||
/***********************************************************************
|
||
*
|
||
* FUNCTION: HandleSliderControl
|
||
*
|
||
* DESCRIPTION:
|
||
*
|
||
* PARAMETERS:
|
||
*
|
||
* RETURNED: Nothing
|
||
*
|
||
***********************************************************************/
|
||
static void HandleSliderControl(EventPtr eventP)
|
||
{
|
||
static Err retval;
|
||
|
||
retval = WaveSeek(eventP->data.ctlSelect.value); // tapCount is percent
|
||
|
||
}
|
||
|
||
/***********************************************************************
|
||
*
|
||
* FUNCTION: MainFormHandleVolumeMounted
|
||
*
|
||
* DESCRIPTION:
|
||
*
|
||
* PARAMETERS:
|
||
*
|
||
* RETURNED: Nothing
|
||
*
|
||
***********************************************************************/
|
||
void MainFormHandleVolumeMounted (Boolean draw)
|
||
{
|
||
if (WaveOpen(WAVE_FILE) == errNone)
|
||
audioState = audioStateOpen;
|
||
else
|
||
audioState = audioStateNoFile;
|
||
|
||
if (draw)
|
||
{
|
||
SetSliderPercent(FrmGetActiveForm(), 0);
|
||
SetControls();
|
||
FrmDrawForm(FrmGetActiveForm());
|
||
}
|
||
}
|
||
|
||
/***********************************************************************
|
||
*
|
||
* FUNCTION: MainFormHandleVolumeUnmounted
|
||
*
|
||
* DESCRIPTION:
|
||
*
|
||
* PARAMETERS:
|
||
*
|
||
* RETURNED: Nothing
|
||
*
|
||
***********************************************************************/
|
||
void MainFormHandleVolumeUnmounted(Boolean draw)
|
||
{
|
||
audioState = audioStateNoVolume;
|
||
|
||
if (draw)
|
||
{
|
||
SetControls();
|
||
FrmDrawForm(FrmGetActiveForm());
|
||
}
|
||
}
|
||
|
||
/***********************************************************************
|
||
*
|
||
* FUNCTION: MainFormResize
|
||
*
|
||
* DESCRIPTION:
|
||
*
|
||
* PARAMETERS:
|
||
*
|
||
* RETURNED:
|
||
*
|
||
***********************************************************************/
|
||
static void MainFormResize(FormPtr frmP, Boolean draw)
|
||
{
|
||
Coord x, y;
|
||
Coord y_diff;
|
||
RectangleType r;
|
||
|
||
/*------------------------------------------------------------------------
|
||
* Get the new extent
|
||
*----------------------------------------------------------------------*/
|
||
WinGetDisplayExtent(&x, &y);
|
||
|
||
/*------------------------------------------------------------------------
|
||
* Get the old extent
|
||
*----------------------------------------------------------------------*/
|
||
FrmGetFormBounds(frmP, &r);
|
||
|
||
/*------------------------------------------------------------------------
|
||
* Calculate change, if none, do nothing
|
||
*----------------------------------------------------------------------*/
|
||
y_diff = y - (r.topLeft.y + r.extent.y);
|
||
if (y_diff == 0)
|
||
return;
|
||
|
||
/*------------------------------------------------------------------------
|
||
* Resize the form
|
||
*----------------------------------------------------------------------*/
|
||
r.extent.y += y_diff;
|
||
WinSetWindowBounds(FrmGetWindowHandle(frmP), &r);
|
||
|
||
/*------------------------------------------------------------------------
|
||
* Move the buttons.
|
||
*----------------------------------------------------------------------*/
|
||
PrvMoveObject(frmP, FrmGetObjectIndex(frmP, MainPlayButton), y_diff, draw);
|
||
PrvMoveObject(frmP, FrmGetObjectIndex(frmP, MainPauseButton), y_diff, draw);
|
||
PrvMoveObject(frmP, FrmGetObjectIndex(frmP, MainRecordButton), y_diff, draw);
|
||
PrvMoveObject(frmP, FrmGetObjectIndex(frmP, MainStopButton), y_diff, draw);
|
||
|
||
if (draw)
|
||
FrmDrawForm(frmP);
|
||
}
|
||
|
||
|
||
/***********************************************************************
|
||
*
|
||
* FUNCTION: MainFormInit
|
||
*
|
||
* DESCRIPTION: This routine initializes the MainForm form.
|
||
*
|
||
* PARAMETERS: frm - pointer to the MainForm form.
|
||
*
|
||
* RETURNED: nothing
|
||
*
|
||
***********************************************************************/
|
||
static void MainFormInit(FormPtr frmP)
|
||
{
|
||
UInt32 features;
|
||
VolumeInfoType info;
|
||
|
||
/*------------------------------------------------------------------------
|
||
* Check to see if we were started using the Aux Button
|
||
*----------------------------------------------------------------------*/
|
||
if (auxButtonPresent && ((KeyCurrentState() & keyBitAux) != 0))
|
||
{
|
||
EventType new_event;
|
||
|
||
new_event.eType = recordStartEvent;
|
||
EvtAddEventToQueue(&new_event);
|
||
launchedFromButton = true;
|
||
}
|
||
else
|
||
launchedFromButton = false;
|
||
|
||
if (vgaPresent)
|
||
{
|
||
VgaFormModify(frmP, vgaFormModify160To240);
|
||
MainFormResize(frmP, false);
|
||
}
|
||
|
||
/*------------------------------------------------------------------------
|
||
* Check to see if unit has record capability
|
||
*----------------------------------------------------------------------*/
|
||
AudioGetSupportedFeatures(&features);
|
||
|
||
if (features & audioFtrRecordWave)
|
||
canRecord = true;
|
||
else
|
||
canRecord = false;
|
||
|
||
WaveInit();
|
||
|
||
if (VFSVolumeInfo(VOLUME_REF_NUM, &info) == errNone)
|
||
{
|
||
if (WaveOpen(WAVE_FILE) == errNone)
|
||
{
|
||
audioState = audioStateOpen;
|
||
SetSliderPercent(FrmGetActiveForm(), 0);
|
||
}
|
||
else
|
||
audioState = audioStateNoFile;
|
||
}
|
||
else
|
||
audioState = audioStateNoVolume;
|
||
|
||
SetControls();
|
||
}
|
||
|
||
|
||
/***********************************************************************
|
||
*
|
||
* FUNCTION: MainFormDoCommand
|
||
*
|
||
* DESCRIPTION: This routine performs the menu command specified.
|
||
*
|
||
* PARAMETERS: command - menu item id
|
||
*
|
||
* RETURNED: nothing
|
||
*
|
||
***********************************************************************/
|
||
static Boolean MainFormDoCommand(UInt16 command)
|
||
{
|
||
Boolean handled = false;
|
||
UInt16 formID;
|
||
FormPtr frmP;
|
||
VgaScreenModeType screenMode;
|
||
VgaRotateModeType rotateMode;
|
||
|
||
formID = (FrmGetFormId (FrmGetActiveForm ()));
|
||
|
||
switch (command)
|
||
{
|
||
case MainOptionsAboutExampleJ:
|
||
MenuEraseStatus(0);
|
||
if (vgaPresent)
|
||
{
|
||
VgaGetScreenMode(&screenMode, &rotateMode);
|
||
VgaSetScreenMode(screenModeScaleToFit, rotateMode);
|
||
}
|
||
frmP = FrmInitForm (AboutForm);
|
||
FrmDoDialog (frmP); // Display the About Box.
|
||
FrmDeleteForm (frmP);
|
||
if (vgaPresent)
|
||
VgaSetScreenMode(screenMode, rotateMode);
|
||
handled = true;
|
||
break;
|
||
}
|
||
|
||
return(handled);
|
||
}
|
||
|
||
|
||
/***********************************************************************
|
||
*
|
||
* FUNCTION: MainFormHandleEvent
|
||
*
|
||
* DESCRIPTION: This routine is the event handler for the
|
||
* "MainForm" of this application.
|
||
*
|
||
* PARAMETERS: eventP - a pointer to an EventType structure
|
||
*
|
||
* RETURNED: true if the event has handle and should not be passed
|
||
* to a higher level handler.
|
||
*
|
||
***********************************************************************/
|
||
Boolean MainFormHandleEvent(EventPtr eventP)
|
||
{
|
||
Boolean handled = false;
|
||
FormPtr frmP;
|
||
|
||
frmP = FrmGetActiveForm();
|
||
|
||
switch (eventP->eType)
|
||
{
|
||
case menuEvent:
|
||
return MainFormDoCommand(eventP->data.menu.itemID);
|
||
|
||
case ctlSelectEvent :
|
||
switch(eventP->data.ctlSelect.controlID)
|
||
{
|
||
case MainPlayButton :
|
||
HandlePlayButton();
|
||
handled = true;
|
||
break;
|
||
case MainPauseButton :
|
||
HandlePauseButton();
|
||
handled = true;
|
||
break;
|
||
case MainStopButton :
|
||
HandleStopButton();
|
||
handled = true;
|
||
break;
|
||
case MainRecordButton :
|
||
HandleRecordButton();
|
||
handled = true;
|
||
break;
|
||
case MainProgressSliderControl :
|
||
HandleSliderControl(eventP);
|
||
handled = true;
|
||
break;
|
||
|
||
}
|
||
break;
|
||
case frmOpenEvent:
|
||
MainFormInit(frmP);
|
||
FrmDrawForm (frmP);
|
||
handled = true;
|
||
break;
|
||
|
||
case displayExtentChangedEvent :
|
||
MainFormResize(frmP, true);
|
||
break;
|
||
|
||
/*------------------------------------------------------------------------
|
||
* Check to see if a card was removed or inserted while we were not the
|
||
* active form.
|
||
*----------------------------------------------------------------------*/
|
||
case winEnterEvent :
|
||
if (cardChangedOccurred)
|
||
{
|
||
SetControls();
|
||
MainFormResize(frmP, true);
|
||
cardChangedOccurred = false;
|
||
}
|
||
break;
|
||
|
||
case frmCloseEvent :
|
||
WaveClose();
|
||
handled = true;
|
||
break;
|
||
|
||
case recordStartEvent :
|
||
HandleRecordButton();
|
||
break;
|
||
|
||
case audioProgressEvent :
|
||
HandleProgress(eventP);
|
||
handled = true;
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
return(handled);
|
||
}
|
||
|
||
|