/* 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; }