Microsoft-3D-Movie-Maker/SRC/STUDIO/STDIOBRW.CPP

688 lines
16 KiB
C++

/* Copyright (c) Microsoft Corporation.
Licensed under the MIT License. */
/***************************************************************************
stdiobrw.cpp
Author: ******
Date: April, 1995
Review Status: Reviewed
This file contains the code which invokes browsers
and applies browser selections.
Studio Independent Browsers:
BASE --> CMH --> GOK --> BRWD (Browser display class)
BRWD --> BRWL (Browser list class; chunky based)
BRWD --> BRWT (Browser text class)
BRWD --> BRWL --> BRWN (Browser named list class)
Studio Dependent Browsers:
BRWD --> BRWT --> BRWA (Browser action class)
BRWD --> BRWL --> BRWP (Browser prop/actor class)
BRWD --> BRWL --> BRWB (Browser background class)
BRWD --> BRWL --> BRWC (Browser camera class)
BRWD --> BRWL --> BRWN --> BRWM (Browser music class)
BRWD --> BRWL --> BRWN --> BRWM --> BRWI (Browser import sound class)
NOTE: In this implementation, browsers are considered to be studio related.
If for any reason one wanted to decouple them from the studio, then it would
be easy for browser.cpp to enqueue cids for
1) SetTagTool and
2) ApplySelection (which would take a browser identifying argument).
The studio (or anyone else) could then apply all browser based selections.
The chunky based browsers come in two categories:
1) Content spanning potentially multiple products (eg, bkgds, actors)
2) Content which is a child of an existing selection.
Browsers of type 1) are cno based. They sort on the basis of the cno of the
thumbnail chunk. The contents of the thumbnail chunk then point to the cno
of the CD content.
Browsers of type 2) are chid based. They sort on the basis of the chid of the
thumbnail chunk. The contents of the thumbnail chunk then point to the chid
of the CD content.
***************************************************************************/
#include "soc.h"
#include "studio.h"
ASSERTNAME
/***************************************************************************
*
* Handle Browser Ready command
* A Browser Ready command signals the invocation of an empty browser
*
* Parameters:
* pcmd - Pointer to the command to process.
* pcmd[0] = kid of Browser (type)
* pcmd[1] = kid first frame. Thumb kid is this + kidBrowserThumbOffset
* pcmd[2] = kid of first control
* pcmd[3] = x,y offsets
*
* Returns:
* fTrue if it handled the command, else fFalse.
*
**************************************************************************/
const long kglpbrcnGrow = 5;
bool STDIO::FCmdBrowserReady(PCMD pcmd)
{
AssertThis(0);
AssertVarMem(pcmd);
bool fSuccess = fFalse;
PBRCN pbrcn = pvNil; // Browser context carryover
PBRWD pbrwd = pvNil;
CKI ckiRoot;
TAG tag;
PTAG ptag;
PMVU pmvu;
long thumSelect;
long sid = ((APP *)vpappb)->SidProduct();
long brwdid = pcmd->rglw[0];
vapp.BeginLongOp();
if (pvNil == _pmvie)
goto LFail;
AssertPo(_pmvie, 0);
// Optionally Save/Retrieve Browser Context
if (_pglpbrcn == pvNil)
{
if (pvNil == (_pglpbrcn = GL::PglNew(size(PBRCN), kglpbrcnGrow)))
goto LFail;
}
// Include optional argument pbrcn if you want context carryover
pbrcn = _PbrcnFromBrwdid(brwdid);
AssertNilOrPo(pbrcn, 0);
switch(brwdid)
{
case kidBrwsBackground:
// Search for background thumbs of any cno
ckiRoot.cno = cnoNil;
ckiRoot.ctg = kctgBkth;
if (pvNil == _pmvie->Pscen())
{
thumSelect = (long)cnoNil;
TrashVar(&sid);
}
else
{
Assert(pvNil != _pmvie->Pscen()->Pbkgd(), "Pbkgd() Nil");
thumSelect = _pmvie->Pscen()->Pbkgd()->Cno();
AssertDo(_pmvie->Pscen()->FGetTagBkgd(&tag), "Missing background event");
sid = tag.sid;
}
pbrwd = (PBRWD)(BRWB::PbrwbNew(_pcrm));
if (pvNil == pbrwd)
goto LFail;
// Create BRCNL for context carryover (optional choice)
if (pbrcn == pvNil)
pbrcn = NewObj BRCNL;
// Selection is cno based
if (!((PBRWB)pbrwd)->FInit(pcmd, kbwsCnoRoot, thumSelect,
sid, ckiRoot, ctgNil, this, (PBRCNL)pbrcn))
{
goto LFail;
}
break;
case kidBrwsCamera:
if (pvNil == _pmvie->Pscen())
goto LFail;
AssertPo(_pmvie->Pscen(), 0);
Assert(pvNil != _pmvie->Pscen()->Pbkgd(), "Pbkgd() Nil");
// Search for camera views, children of the current bkgd
ckiRoot.ctg = kctgBkth;
ckiRoot.cno = _pmvie->Pscen()->Pbkgd()->Cno();
thumSelect = _pmvie->Pscen()->Pbkgd()->Icam();
pbrwd = (PBRWD)(BRWC::PbrwcNew(_pcrm));
if (pvNil == pbrwd)
goto LFail;
// Create BRCNL for context carryover (optional choice)
if (pbrcn == pvNil)
pbrcn = NewObj BRCNL;
AssertDo(_pmvie->Pscen()->FGetTagBkgd(&tag), "Missing background event");
if (!((PBRWC)pbrwd)->FInit(pcmd, kbwsChid, thumSelect,
tag.sid, ckiRoot, kctgCath, this, (PBRCNL)pbrcn))
{
goto LFail;
}
break;
case kidBrwsProp:
ckiRoot.ctg = kctgPrth;
pbrwd = (PBRWD)(BRWP::PbrwpNew(_pcrm, kidPropGlass));
goto LActor;
case kidBrwsActor:
ckiRoot.ctg = kctgTmth;
pbrwd = (PBRWD)(BRWP::PbrwpNew(_pcrm, kidActorGlass));
LActor:
ckiRoot.cno = cnoNil;
Assert(pvNil != _pmvie->Pscen(), "Actor browser requires scene");
thumSelect = ivNil;
if (pvNil == pbrwd)
goto LFail;
// Create BRCNL for context carryover (optional choice)
if (pbrcn == pvNil)
pbrcn = NewObj BRCNL;
if (!((PBRWP)pbrwd)->FInit(pcmd, kbwsCnoRoot, thumSelect,
0, ckiRoot, ctgNil, this, (PBRCNL)pbrcn))
{
goto LFail;
}
break;
case kidBrwsAction:
if ((pvNil == _pmvie->Pscen()) ||
(pvNil == _pmvie->Pscen()->PactrSelected()))
{
Bug("No actor selected in action browser");
goto LFail;
}
thumSelect = _pmvie->Pscen()->PactrSelected()->AnidCur();
pbrwd = (PBRWD)BRWA::PbrwaNew(_pcrm);
if (pvNil == pbrwd)
goto LFail;
// Build the string table before initializing
if (!((PBRWA)pbrwd)->FBuildGst(_pmvie->Pscen()))
goto LFail;
if (!((PBRWT)pbrwd)->FInit(pcmd, thumSelect, thumSelect, this))
goto LFail;
break;
case kidSSorterBackground:
if (SCRT::PscrtNew(brwdid, _pmvie, this, _pcrm) == pvNil)
PushErc(ercSocCantInitSceneSort);
vapp.EndLongOp();
return fTrue;
case kidBrwsFX:
ckiRoot.ctg = kctgSfth;
pbrwd = (PBRWD)(BRWM::PbrwmNew(_pcrm, kidFXGlass, stySfx, this));
goto LMusic;
case kidBrwsSpeech:
ckiRoot.ctg = kctgSvth;
pbrwd = (PBRWD)(BRWM::PbrwmNew(_pcrm, kidSpeechGlass, stySpeech, this));
goto LMusic;
case kidBrwsMidi:
ckiRoot.ctg = kctgSmth;
pbrwd = (PBRWD)(BRWM::PbrwmNew(_pcrm, kidMidiGlass, styMidi, this));
LMusic:
if (pvNil == pbrwd)
goto LFail;
// Search for background thumbs of any cno
ckiRoot.cno = cnoNil;
thumSelect = (long)cnoNil;
// Create BRCNL for context carryover (optional choice)
if (pbrcn == pvNil)
pbrcn = NewObj BRCNL;
pmvu = (PMVU)(Pmvie()->PddgGet(0));
ptag = pmvu->PtagTool();
if (ptag->sid != ksidInvalid)
{
thumSelect = ptag->cno;
sid = ptag->sid;
}
// Selection is cno based
if (!((PBRWM)pbrwd)->FInit(pcmd, kbwsCnoRoot, thumSelect, sid,
ckiRoot, ctgNil, this, (PBRCNL)pbrcn))
{
goto LFail;
}
break;
//
// The import browser is set up on top of the normal sound browser
// rglw[1] = pfniMovie of movie to be scanned.
//
case kidBrwsImportFX:
ckiRoot.ctg = kctgSfth;
pbrwd = (PBRWD)(BRWI::PbrwiNew(_pcrm, kidSoundsImportGlass, stySfx));
goto LImport;
case kidBrwsImportSpeech:
ckiRoot.ctg = kctgSvth;
pbrwd = (PBRWD)(BRWI::PbrwiNew(_pcrm, kidSoundsImportGlass, stySpeech));
goto LImport;
case kidBrwsImportMidi:
ckiRoot.ctg = kctgSmth;
pbrwd = (PBRWD)(BRWI::PbrwiNew(_pcrm, kidSoundsImportGlass, styMidi));
LImport:
if (pvNil == pbrwd)
goto LFail;
// Build the string table before initializing the BRWD
if (!((PBRWI)pbrwd)->FInit(pcmd, ckiRoot, this))
{
goto LFail;
}
break;
case kidRollCallProp:
Assert(pvNil == _pbrwrProp, "Roll Call browser already up");
_pbrwrProp = BRWR::PbrwrNew(_pcrm, kidRollCallProp);
pbrwd = (PBRWD)_pbrwrProp;
if (pvNil == pbrwd)
goto LFail;
// Create the cno map from tmpl-->gokd
if (_pglcmg == pvNil)
{
if (pvNil == (_pglcmg = GL::PglNew(size(CMG), kglcmgGrow)))
goto LFail;
_pglcmg->SetMinGrow(kglcmgGrow);
}
if (!_pbrwrProp->FInit(pcmd, kctgPrth, ivNil, this))
goto LFail;
break;
case kidRollCallActor:
Assert(pvNil == _pbrwrActr, "Roll Call browser already up");
_pbrwrActr = BRWR::PbrwrNew(_pcrm, kidRollCallActor);
pbrwd = (PBRWD)_pbrwrActr;
if (pvNil == pbrwd)
goto LFail;
// Create the cno map from tmpl-->gokd
if (_pglcmg == pvNil)
{
if (pvNil == (_pglcmg = GL::PglNew(size(CMG), kglcmgGrow)))
goto LFail;
_pglcmg->SetMinGrow(kglcmgGrow);
}
if (!_pbrwrActr->FInit(pcmd, kctgTmth, ivNil, this))
goto LFail;
break;
default:
RawRtn();
break;
}
Assert(pvNil != pbrwd, "Logic error");
pbrwd->FDraw(); // Ignore failure : reported elsewhere
//
// Optionally Add new browser to the gl for context
// carryover between browser instantiations
//
if (pvNil != pbrcn && pvNil == _PbrcnFromBrwdid(brwdid))
{
if (!_pglpbrcn->FAdd(&pbrcn))
{
goto LFail;
}
}
fSuccess = fTrue;
LFail:
if (!fSuccess)
{
ReleasePpo(&pbrcn);
ReleasePpo(&pbrwd);
}
vpcex->EnqueueCid(cidBrowserVisible, pvNil, pvNil, fSuccess ? 1 : 0); // For projects
vapp.EndLongOp();
return fTrue;
}
/***************************************************************************
*
* Destroy browser context (when Studio destructs)
*
**************************************************************************/
void STDIO::ReleaseBrcn(void)
{
long ipbrcn;
PBRCN pbrcn;
if (pvNil == _pglpbrcn)
return;
for (ipbrcn = 0; ipbrcn < _pglpbrcn->IvMac(); ipbrcn++)
{
_pglpbrcn->Get(ipbrcn, &pbrcn);
ReleasePpo(&pbrcn);
}
ReleasePpo(&_pglpbrcn);
}
/***************************************************************************
*
* Locate a browser pbrwd
*
**************************************************************************/
PBRCN STDIO::_PbrcnFromBrwdid(long brwdid)
{
AssertThis(0);
long ipbrcn;
PBRCN pbrcn;
for (ipbrcn = 0; ipbrcn < _pglpbrcn->IvMac(); ipbrcn++)
{
_pglpbrcn->Get(ipbrcn, &pbrcn);
if (pbrcn->brwdid == brwdid)
{
return pbrcn;
}
}
return pvNil;
}
/***************************************************************************
*
* Apply a Camera Selection. (Browser callback)
* thumSelect is an index and a chid
*
**************************************************************************/
void BRWC::_ApplySelection(long thumSelect, long sid)
{
AssertThis(0);
PMVU pmvu;
_pstdio->Pmvie()->Pscen()->FChangeCam(thumSelect);
// Update the tool
pmvu = (PMVU)(_pstdio->Pmvie()->PddgActive());
AssertPo(pmvu, 0);
pmvu->SetTool(toolDefault);
// Update the UI
_pstdio->Pmvie()->Pmcc()->ChangeTool(toolDefault);
}
/***************************************************************************
*
* Apply a Background Selection. (Browser callback)
* thumSelect is a cno
*
**************************************************************************/
void BRWB::_ApplySelection(long thumSelect, long sid)
{
AssertThis(0);
TAG tag;
CMD cmd;
PMVU pmvu;
tag.sid = sid;
tag.pcrf = pvNil;
tag.ctg = kctgBkgd;
tag.cno = (CNO)thumSelect;
ClearPb(&cmd, size(cmd));
cmd.cid = cidNewScene;
cmd.pcmh = _pstdio;
Assert(size(TAG) <= size(cmd.rglw), "Insufficient space in rglw");
*((PTAG)&cmd.rglw) = tag;
vpcex->EnqueueCmd(&cmd);
// Update the tool
pmvu = (PMVU)(_pstdio->Pmvie()->PddgActive());
AssertPo(pmvu, 0);
pmvu->SetTool(toolDefault);
// Update the UI
_pstdio->Pmvie()->Pmcc()->ChangeTool(toolDefault);
return;
}
/***************************************************************************
*
* Apply an Actor Selection.
*
* thumSelect is a cno
*
*
**************************************************************************/
void BRWP::_ApplySelection(long thumSelect, long sid)
{
AssertThis(0);
TAG tag;
PMVU pmvu;
pmvu = (PMVU)(_pstdio->Pmvie()->PddgGet(0));
if (pmvu == pvNil)
{
Warn("No pmvu");
return;
}
AssertPo(pmvu, 0);
tag.sid = sid;
tag.pcrf = pvNil;
tag.ctg = kctgTmpl;
tag.cno = (CNO)thumSelect;
if (!_pstdio->Pmvie()->FInsActr(&tag))
goto LFail;
pmvu->StartPlaceActor(fTrue);
LFail:
return;
}
/***************************************************************************
*
* Apply an Action Selection.
*
* thumSelect is a chid
*
**************************************************************************/
void BRWA::_ApplySelection(long thumSelect, long sid)
{
AssertThis(0);
AssertPo(_pstdio->Pmvie(), 0);
PACTR pactr;
PMVU pmvu;
PGOK pgok;
// Apply the action to the actor
pactr = _pstdio->Pmvie()->Pscen()->PactrSelected();
if (!pactr->FSetAction(thumSelect, _celnStart, fFalse))
return; // Error reported earlier
// Update the tool
pmvu = (PMVU)(_pstdio->Pmvie()->PddgActive());
AssertPo(pmvu, 0);
pmvu->SetTool(toolRecordSameAction);
// Update the UI
_pstdio->Pmvie()->Pmcc()->ChangeTool(toolRecordSameAction);
// Reset the studio action button state (record will be depressed)
pgok = (PGOK)vapp.Pkwa()->PgobFromHid(kidActorsActionBrowser);
if ((pgok != pvNil) && pgok->FIs(kclsGOK))
{
Assert(pgok->FIs(kclsGOK), "Invalid class");
pgok->FChangeState(kstDefault);
}
return;
}
/***************************************************************************
*
* Apply a Music Selection.
*
* thumSelect is a cnoContent
*
**************************************************************************/
void BRWM::_ApplySelection(long thumSelect, long sid)
{
AssertThis(0);
AssertPo(_pstdio->Pmvie(), 0);
PGOK pgok;
PMVU pmvu;
TAG tag;
BOOL fClick = fTrue;
pmvu = (PMVU)(_pstdio->Pmvie()->PddgGet(0));
AssertPo(pmvu, 0);
tag.ctg = kctgMsnd;
tag.cno = (CNO)thumSelect;
tag.sid = sid;
if (ksidUseCrf != sid)
tag.pcrf = pvNil;
else
{
if (!_pstdio->Pmvie()->FEnsureAutosave(&_pcrf))
return;
AssertDo(vptagm->FOpenTag(&tag, _pcrf),
"Should never fail when not copying the tag");
}
// Set the tool to "play once", if necessary
pgok = (PGOK)vpapp->Pkwa()->PgobFromHid(kidSoundsLooping);
if (pgok != pvNil && pgok->FIs(kclsGOK) && (pgok->Sno() == kstSelected))
{
fClick = fFalse;
}
pgok = (PGOK)vpapp->Pkwa()->PgobFromHid(kidSoundsAttachToCell);
if (pgok != pvNil && pgok->FIs(kclsGOK) && (pgok->Sno() == kstSelected) && (_sty != styMidi))
{
fClick = fFalse;
}
if (fClick)
{
pgok = (PGOK)vpapp->Pkwa()->PgobFromHid(kidSoundsPlayOnce);
if (pgok != pvNil && pgok->FIs(kclsGOK) && (pgok->Sno() != kstSelected))
{
AssertPo(pgok, 0);
vpcex->EnqueueCid(cidClicked, pgok, pvNil, pvNil);
}
}
pmvu->SetTagTool(&tag);
TAGM::CloseTag(&tag);
return;
}
/***************************************************************************
*
* Apply an Import Music Selection.
* Copy the msnd chunk from the open BRWI movie to the current movie
* Then notify the underlying sound browser to update
*
* thumSelect is a cnoContent
*
**************************************************************************/
void BRWI::_ApplySelection(long thumSelect, long sid)
{
AssertThis(0);
AssertPo(_pstdio->Pmvie(), 0);
CNO cnoDest;
long kidBrws;
switch (_sty)
{
case styMidi:
kidBrws = kidMidiGlass;
break;
case stySfx:
kidBrws = kidFXGlass;
break;
case stySpeech:
kidBrws = kidSpeechGlass;
break;
default:
Bug("Invalid _sty");
break;
}
if (pvNil == _pcrf || pvNil == _pcrf->Pcfl())
return;
// Copy sound from _pcrf->Pcfl() to current movie
vpappb->BeginLongOp();
if (!_pstdio->Pmvie()->FCopyMsndFromPcfl(_pcrf->Pcfl(), (CNO)thumSelect, &cnoDest))
{
vpappb->EndLongOp();
return;
}
vpappb->EndLongOp();
// Select the item, extend lists and hilite it
vpcex->EnqueueCid(cidBrowserSelectThum, vpappb->PcmhFromHid(kidBrws),
pvNil, cnoDest, sid, 1, 1);
return;
}
/***************************************************************************
*
* Apply a Roll Call Selection.
* thumSelect equals ithum
*
**************************************************************************/
void BRWR::_ApplySelection(long thumSelect, long sid)
{
AssertThis(0);
PMVU pmvu;
PMVIE pmvie = _pstdio->Pmvie();
long arid;
STN stn;
long cactRef;
long iarid = _IaridFromIthum(thumSelect);
if (!pmvie->FGetArid(iarid, &arid, &stn, &cactRef))
return;
_fApplyingSel = fTrue;
pmvu = (PMVU)pmvie->PddgActive();
pmvie->FChooseArid(arid);
if (!pmvu->FActrMode())
{
pmvu->SetTool(toolCompose);
_pstdio->ChangeTool(toolCompose);
}
_fApplyingSel = fFalse;
}