mirror of
https://github.com/microsoft/Microsoft-3D-Movie-Maker.git
synced 2024-11-14 15:35:06 +00:00
943 lines
23 KiB
C++
943 lines
23 KiB
C++
/* Copyright (c) Microsoft Corporation.
|
|
Licensed under the MIT License. */
|
|
|
|
/******************************************************************************
|
|
Author: ******
|
|
Project: Socrates
|
|
Review Status: Reviewed
|
|
|
|
Main module for the scene sorter class.
|
|
|
|
************************************************************ PETED ***********/
|
|
|
|
#include "studio.h"
|
|
|
|
ASSERTNAME
|
|
|
|
BEGIN_CMD_MAP(SCRT, GOK)
|
|
ON_CID_ME(cidSceneSortInit, FCmdInit, pvNil)
|
|
ON_CID_ME(cidSceneSortSelect, FCmdSelect, pvNil)
|
|
ON_CID_ME(cidSceneSortInsert, FCmdInsert, pvNil)
|
|
ON_CID_ME(cidSceneSortScroll, FCmdScroll, pvNil)
|
|
ON_CID_ME(cidSceneSortNuke, FCmdNuke, pvNil)
|
|
ON_CID_ME(cidSceneSortOk, FCmdDismiss, pvNil)
|
|
ON_CID_ME(cidSceneSortCancel, FCmdDismiss, pvNil)
|
|
ON_CID_ME(cidSceneSortPortfolio, FCmdPortfolio, pvNil)
|
|
ON_CID_ME(cidSceneSortTransition, FCmdTransition, pvNil)
|
|
END_CMD_MAP_NIL()
|
|
|
|
|
|
RTCLASS(SCRT)
|
|
|
|
#ifdef DEBUG
|
|
void SCRT::AssertValid(ulong grf)
|
|
{
|
|
SCRT_PAR::AssertValid(0);
|
|
if (_iscenMac > 0)
|
|
AssertIn(_iscenCur, 0, _iscenMac);
|
|
else
|
|
Assert(_iscenCur == 0, "Non-zero _iscenCur for empty movie");
|
|
AssertIn(_iscenTop, 0, _iscenMac + 1);
|
|
|
|
/* The CMVI has loose rules about the format of its data structures, but
|
|
it's important to the SCRT that we keep things in the right order. */
|
|
if (_cmvi.pglscend != pvNil)
|
|
{
|
|
long imviedMac;
|
|
|
|
AssertPo(_cmvi.pglscend, 0);
|
|
AssertPo(_cmvi.pglmvied, 0);
|
|
imviedMac = _cmvi.pglmvied->IvMac();
|
|
for (long iscend = 0; iscend < _cmvi.pglscend->IvMac(); iscend++)
|
|
{
|
|
SCEND scend;
|
|
|
|
_cmvi.pglscend->Get(iscend, &scend);
|
|
Assert(iscend < _iscenMac ?
|
|
!scend.fNuked : scend.fNuked, "Bad GL of SCENDs");
|
|
Assert(scend.imvied < imviedMac, "Bogus scene entry in pglscend");
|
|
}
|
|
}
|
|
}
|
|
|
|
void SCRT::MarkMem(void)
|
|
{
|
|
AssertThis(0);
|
|
|
|
SCRT_PAR::MarkMem();
|
|
MarkMemObj(_pmvie);
|
|
_cmvi.MarkMem();
|
|
}
|
|
#endif /* DEBUG */
|
|
|
|
SCRT::SCRT(PGCB pgcb) : SCRT_PAR(pgcb)
|
|
{
|
|
Assert(_pmvie == pvNil, "SCRT block not cleared");
|
|
Assert(_pstdio == pvNil, "SCRT block not cleared");
|
|
Assert(_cmvi.pglscend == pvNil, "SCRT block not cleared");
|
|
Assert(_cmvi.pglmvied == pvNil, "SCRT block not cleared");
|
|
Assert(_fError == fFalse, "SCRT block not cleared");
|
|
Assert(_fInited == fFalse, "SCRT block not cleared");
|
|
Assert(_iscenMac == 0, "SCRT block not cleared");
|
|
}
|
|
|
|
SCRT::~SCRT(void)
|
|
{
|
|
PGOB pgob;
|
|
|
|
/* We might get released on Quit without exiting the Scene Sorter. */
|
|
if (_cmvi.pglscend != pvNil || _cmvi.pglmvied != pvNil)
|
|
_cmvi.Empty();
|
|
if (_pmvie != pvNil)
|
|
ReleasePpo(&_pmvie);
|
|
|
|
/* Kill the glass GOB (it's not a child of me) */
|
|
pgob = vpapp->Pkwa()->PgobFromHid(kidGenericDisableGlass);
|
|
ReleasePpo(&pgob);
|
|
|
|
if (_fInited)
|
|
vpapp->EnableAccel();
|
|
|
|
/* Report generic error */
|
|
if (_fError)
|
|
PushErc(ercSocSceneSortError);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
PscrtNew
|
|
Allocates and initializes a brand new SCRT. If any necessary
|
|
initialization fails, cleans up and returns a nil pointer.
|
|
|
|
Arguments:
|
|
long hid -- the command hander ID for the SCRT
|
|
|
|
Returns: the pointer to the new SCRT, pvNil if the routine fails
|
|
|
|
************************************************************ PETED ***********/
|
|
PSCRT SCRT::PscrtNew(long hid, PMVIE pmvie, PSTDIO pstdio, PRCA prca)
|
|
{
|
|
AssertPo(pmvie, 0);
|
|
AssertPo(pstdio, 0);
|
|
|
|
PSCRT pscrt = pvNil;
|
|
PGOB pgobPar;
|
|
RC rcRel;
|
|
GCB gcb;
|
|
|
|
if ((pgobPar = vapp.Pkwa()->PgobFromHid(kidBackground)) == pvNil)
|
|
{
|
|
Bug("Couldn't find background GOB");
|
|
goto LFail;
|
|
}
|
|
|
|
rcRel.Set(krelZero, krelZero, krelOne, krelOne);
|
|
gcb.Set(hid, pgobPar, fgobNil, kginDefault, pvNil, &rcRel);
|
|
|
|
if ((pscrt = NewObj SCRT(&gcb)) == pvNil)
|
|
goto LFail;
|
|
|
|
if (!pscrt->_FInit(vpapp->Pkwa(), hid, prca))
|
|
goto LOom;
|
|
if (!pscrt->_FEnterState(ksnoInit))
|
|
{
|
|
Warn("GOK immediately destroyed!");
|
|
pscrt = pvNil;
|
|
goto LFail;
|
|
}
|
|
|
|
if (!pmvie->FAddToCmvi(&pscrt->_cmvi, &pscrt->_iscenMac))
|
|
{
|
|
LOom:
|
|
ReleasePpo(&pscrt);
|
|
goto LFail;
|
|
}
|
|
|
|
pscrt->_pmvie = pmvie;
|
|
pscrt->_pmvie->AddRef();
|
|
pscrt->_iscenCur = LwMax(0, pscrt->_pmvie->Iscen());
|
|
pscrt->_iscenMac = pscrt->_pmvie->Cscen();
|
|
pscrt->_pstdio = pstdio;
|
|
|
|
LFail:
|
|
return pscrt;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
_ErrorExit
|
|
Handle an error. Destroys the easel and enqueues our cancel cid.
|
|
|
|
************************************************************ PETED ***********/
|
|
void SCRT::_ErrorExit(void)
|
|
{
|
|
/* If someone's already reported an error, don't do any more work */
|
|
if (_fError)
|
|
return;
|
|
_fError = fTrue;
|
|
|
|
/* Notify myself that we're exiting */
|
|
vpcex->EnqueueCid(cidSceneSortCancel, this);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
FCmdInit
|
|
Initializes the Scene Sorter with the information about the easel
|
|
in kidspace.
|
|
|
|
Arguments:
|
|
PCMD pcmd -- pointer to the CMD data. Extra params are as follows:
|
|
rglw[0] -- kid of the first thumbnail frame GOK
|
|
rglw[1] -- kid of the first scrollbar GOK button (scroll up)
|
|
rglw[2] -- number of GOKs in a single frame
|
|
|
|
Returns: fTrue if the command was handled by this routine.
|
|
|
|
************************************************************ PETED ***********/
|
|
bool SCRT::FCmdInit(PCMD pcmd)
|
|
{
|
|
AssertThis(0);
|
|
|
|
bool fSuccess = fFalse;
|
|
long kidCur, kidThumb;
|
|
PGOK pgokFrame;
|
|
|
|
/* If I'm already inited, this must be for some other scene sorter */
|
|
if (_fInited)
|
|
return fFalse;
|
|
|
|
_fInited = fTrue;
|
|
vpapp->DisableAccel();
|
|
|
|
_kidFrameMin = pcmd->rglw[0];
|
|
_kidScbtnsMin = pcmd->rglw[1];
|
|
_cgokFrame = pcmd->rglw[2];
|
|
_cfrmPage = 0;
|
|
|
|
kidThumb = _kidFrameMin - 1;
|
|
kidCur = _kidFrameMin;
|
|
|
|
while ((pgokFrame = (PGOK)vpapp->Pkwa()->PgobFromHid(kidCur)) != pvNil)
|
|
{
|
|
PGOMP pgomp;
|
|
PGOB pgobThumb;
|
|
|
|
Assert(pgokFrame->FIs(kclsGOK), "Frame GOB isn't a GOK");
|
|
|
|
pgobThumb = (PGOK)pgokFrame->PgobFirstChild();
|
|
Assert(pgobThumb != pvNil, "Frame has no children");
|
|
|
|
pgomp = GOMP::PgompNew(pgobThumb, kidThumb--);
|
|
if (pgomp == pvNil)
|
|
goto LFail;
|
|
_cfrmPage++;
|
|
kidCur += _cgokFrame;
|
|
}
|
|
|
|
_cfrmPage--;
|
|
|
|
_iscenTop = (_iscenCur / _cfrmPage) * _cfrmPage;
|
|
fSuccess = _FResetThumbnails(fFalse);
|
|
|
|
LFail:
|
|
if (!fSuccess)
|
|
_ErrorExit();
|
|
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
FCmdSelect
|
|
Selects the scene corresponding to the given thumbnail frame.
|
|
|
|
Arguments:
|
|
PCMD pcmd -- pointer to the CMD data. Extra params are as follows:
|
|
rglw[0] -- the kid of the thumbnail frame
|
|
|
|
Returns: fTrue if the command was handled by this routine.
|
|
|
|
************************************************************ PETED ***********/
|
|
bool SCRT::FCmdSelect(PCMD pcmd)
|
|
{
|
|
AssertThis(0);
|
|
Assert(pcmd->rglw[0] - _kidFrameMin < _cfrmPage * _cgokFrame,
|
|
"Bogus kid for select");
|
|
Assert(_iscenMac > 0, "Can't select scene in an empty movie");
|
|
|
|
long iscen;
|
|
|
|
iscen = _IscenFromKid(pcmd->rglw[0]);
|
|
if (iscen < _iscenMac)
|
|
{
|
|
_iscenCur = iscen;
|
|
|
|
/* Fill in thumbnail for selection GOB */
|
|
if (_FResetThumbnails(fFalse))
|
|
_SetSelectionVis(fTrue);
|
|
else
|
|
_ErrorExit();
|
|
}
|
|
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
FCmdInsert
|
|
Inserts the currently selected scene before the scene that
|
|
corresponds to the given thumbnail frame. If the given thumbnail
|
|
frame is larger than the last visible thumbnail frame, the scene is
|
|
inserted after the last scene visible on the easel.
|
|
|
|
Arguments:
|
|
PCMD pcmd -- pointer to the CMD data. Extra params are as follows:
|
|
rglw[0] -- the kid of the frame to insert the scene before
|
|
|
|
Returns: fTrue if the command was handled by this routine.
|
|
|
|
************************************************************ PETED ***********/
|
|
bool SCRT::FCmdInsert(PCMD pcmd)
|
|
{
|
|
AssertThis(0);
|
|
Assert(pcmd->rglw[0] - _kidFrameMin <= _cfrmPage * _cgokFrame,
|
|
"Bogus kid for insert");
|
|
|
|
long iscenTo = _IscenFromKid(pcmd->rglw[0]);
|
|
|
|
if (iscenTo != _iscenCur)
|
|
{
|
|
AssertIn(iscenTo, 0, _iscenMac+1);
|
|
|
|
_cmvi.pglscend->Move(_iscenCur, iscenTo);
|
|
if (iscenTo > _iscenCur)
|
|
iscenTo--;
|
|
_iscenCur = iscenTo;
|
|
}
|
|
|
|
/* Refill the thumbnails */
|
|
if (!_FResetThumbnails(fFalse))
|
|
_ErrorExit();
|
|
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
FCmdScroll
|
|
Scrolls the thumbnails by the given number of frames. The sign of
|
|
the number of frames indicates whether to scroll forward (positive)
|
|
or backward (negative). Sets the selected frame to kstBrowserSelected
|
|
if we're not drag & drop, or to kstBrowserScrollingSel if we are.
|
|
|
|
Arguments:
|
|
PCMD pcmd -- pointer to the CMD data. Extra params are as follows:
|
|
rglw[0] -- the number of frames to scroll
|
|
rglw[1] -- non-zero if we're scrolling during drag & drop
|
|
|
|
Returns: fTrue if the command was handled by this routine.
|
|
|
|
************************************************************ PETED ***********/
|
|
bool SCRT::FCmdScroll(PCMD pcmd)
|
|
{
|
|
AssertThis(0);
|
|
|
|
bool fHideSel = pcmd->rglw[1] != 0;
|
|
long iscenT;
|
|
|
|
iscenT = _iscenTop + pcmd->rglw[0];
|
|
if (FIn(iscenT, 0, _iscenMac) && _iscenTop != iscenT)
|
|
{
|
|
_SetSelectionVis(fFalse, fHideSel);
|
|
_iscenTop = iscenT;
|
|
}
|
|
|
|
/* Refill the thumbnails */
|
|
if (!_FResetThumbnails(fHideSel))
|
|
_ErrorExit();
|
|
|
|
_SetSelectionVis(fTrue, fHideSel);
|
|
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
_EnableScroll
|
|
Enables or disables the scrolling buttons, as appropriate.
|
|
|
|
************************************************************ PETED ***********/
|
|
void SCRT::_EnableScroll(void)
|
|
{
|
|
PGOK pgok;
|
|
|
|
/* Enable or disable scroll up */
|
|
pgok = (PGOK)vapp.Pkwa()->PgobFromHid(_kidScbtnsMin);
|
|
if (pgok != pvNil)
|
|
{
|
|
long lwState;
|
|
|
|
lwState = (_iscenTop > 0) ? kstBrowserEnabled : kstBrowserDisabled;
|
|
Assert(pgok->FIs(kclsGOK), "Scroll up button is not a GOK");
|
|
if (pgok->Sno() != lwState)
|
|
pgok->FChangeState(lwState);
|
|
}
|
|
else
|
|
Bug("Can't find scroll up button");
|
|
|
|
/* Enable or disable scroll down */
|
|
pgok = (PGOK)vapp.Pkwa()->PgobFromHid(_kidScbtnsMin + 1);
|
|
if (pgok != pvNil)
|
|
{
|
|
long lwState;
|
|
|
|
lwState = (_iscenTop + _cfrmPage < _iscenMac) ?
|
|
kstBrowserEnabled : kstBrowserDisabled;
|
|
Assert(pgok->FIs(kclsGOK), "Scroll down button is not a GOK");
|
|
if (pgok->Sno() != lwState)
|
|
pgok->FChangeState(lwState);
|
|
}
|
|
else
|
|
Bug("Can't find scroll down button");
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
FCmdNuke
|
|
Deletes the currently selected scene from the movie. Makes the
|
|
following scene the currently selected scene, unless there is no
|
|
such scene, in which case the scene immediately before the deleted
|
|
scene is the new currently selected scene.
|
|
|
|
Arguments:
|
|
PCMD pcmd -- pointer to the CMD data. No additional parameters.
|
|
|
|
Returns: fTrue if the command was handled by this routine.
|
|
|
|
************************************************************ PETED ***********/
|
|
bool SCRT::FCmdNuke(PCMD pcmd)
|
|
{
|
|
AssertThis(0);
|
|
Assert(_iscenMac > 0, "Can't nuke a scene from an empty movie");
|
|
|
|
SCEND scend;
|
|
|
|
_cmvi.pglscend->Get(_iscenCur, &scend);
|
|
Assert(!scend.fNuked, "Nuking an already nuked scene");
|
|
scend.fNuked = fTrue;
|
|
_cmvi.pglscend->Put(_iscenCur, &scend);
|
|
_cmvi.pglscend->Move(_iscenCur, _cmvi.pglscend->IvMac());
|
|
_iscenMac--;
|
|
if (_iscenMac > 0 && _iscenMac == _iscenCur)
|
|
_iscenCur--;
|
|
|
|
/* Refill the thumbnails */
|
|
if (!_FResetThumbnails(fFalse))
|
|
_ErrorExit();
|
|
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
FCmdDismiss
|
|
Alerts the Scene Sorter that the easel is about to go away. If the
|
|
easel was not cancelled, the changes made in the easel are applied
|
|
to the movie.
|
|
|
|
Arguments:
|
|
PCMD pcmd -- pointer to the CMD data. Checks cid to determine ok/cancel
|
|
|
|
Returns: fTrue if the command was handled by this routine.
|
|
|
|
************************************************************ PETED ***********/
|
|
bool SCRT::FCmdDismiss(PCMD pcmd)
|
|
{
|
|
AssertThis(0);
|
|
|
|
PMVU pmvu;
|
|
|
|
if (pcmd->cid == cidSceneSortOk)
|
|
{
|
|
vapp.BeginLongOp();
|
|
if (_pmvie->FSetCmvi(&_cmvi))
|
|
{
|
|
if (_pmvie->Cscen() > 0 && _pmvie->Iscen() != _iscenCur)
|
|
_pmvie->FSwitchScen(_iscenCur);
|
|
}
|
|
else
|
|
_fError = fTrue;
|
|
_pmvie->ClearUndo();
|
|
vapp.EndLongOp();
|
|
}
|
|
|
|
/* Change to the tool for scenes */
|
|
pmvu = (PMVU)(_pmvie->PddgActive());
|
|
AssertPo(pmvu, 0);
|
|
pmvu->SetTool(toolDefault);
|
|
_pstdio->ChangeTool(toolDefault);
|
|
|
|
/* Clean up the internal data structures */
|
|
_cmvi.Empty();
|
|
ReleasePpo(&_pmvie);
|
|
|
|
Release();
|
|
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
FCmdPortfolio
|
|
Brings up the portfolio so that the user can append movies from file.
|
|
|
|
Arguments:
|
|
PCMD pcmd -- pointer to the CMD data. No additional parameters.
|
|
|
|
Returns: fTrue if the command was handled by this routine.
|
|
|
|
************************************************************ PETED ***********/
|
|
bool SCRT::FCmdPortfolio(PCMD pcmd)
|
|
{
|
|
AssertThis(0);
|
|
|
|
FNI fni;
|
|
MCC mcc(2, 2, 0);
|
|
PMVIE pmvie = pvNil;
|
|
|
|
if (!_pstdio->FGetFniMovieOpen(&fni))
|
|
goto LFail;
|
|
|
|
/* Specific reasons for failures are reported by lower-level routines.
|
|
There should be no reason to display an error here. */
|
|
pmvie = MVIE::PmvieNew(vpapp->FSlowCPU(), &mcc, &fni, cnoNil);
|
|
if (pmvie == pvNil)
|
|
goto LFail;
|
|
|
|
if (!pmvie->FAddToCmvi(&_cmvi, &_iscenMac))
|
|
goto LFail;
|
|
|
|
/* Refill the thumbnails */
|
|
if (!_FResetThumbnails(fFalse))
|
|
_ErrorExit();
|
|
|
|
LFail:
|
|
ReleasePpo(&pmvie);
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
FCmdTransition
|
|
Sets the transition for the scene corresponding to the given frame.
|
|
|
|
Arguments:
|
|
PCMD pcmd -- pointer to command data. Extra parms are as follows:
|
|
rglw[0] -- GOK id of the frame
|
|
rglw[1] -- which transition to use
|
|
|
|
Returns: fTrue if the command was handled by this routine
|
|
|
|
************************************************************ PETED ***********/
|
|
bool SCRT::FCmdTransition(PCMD pcmd)
|
|
{
|
|
AssertThis(0);
|
|
Assert(_iscenMac > 0, "Can't set transition when movie is empty");
|
|
|
|
long iscen = _IscenFromKid(pcmd->rglw[0]);
|
|
SCEND scend;
|
|
PGOK pgokFrame = (PGOK)vapp.Pkwa()->PgobFromHid(pcmd->rglw[0]);
|
|
|
|
if (pgokFrame == pvNil)
|
|
{
|
|
Bug("kid doesn't exist");
|
|
return fTrue;
|
|
}
|
|
Assert(pgokFrame->FIs(kclsGOK), "kid isn't a GOK");
|
|
|
|
AssertIn(iscen, 0, _iscenMac);
|
|
_cmvi.pglscend->Get(iscen, &scend);
|
|
scend.trans = _TransFromLw(pcmd->rglw[1] - 1);
|
|
_cmvi.pglscend->Put(iscen, &scend);
|
|
|
|
if (_FResetTransition(pgokFrame, scend.trans))
|
|
pgokFrame->InvalRc(pvNil);
|
|
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
_SetSelectionVis
|
|
Shows or hides the current selection.
|
|
|
|
Arguments:
|
|
bool fShow -- fTrue if we're to make the selection different from the
|
|
other frames
|
|
bool fHideSel -- fTrue if the selection state is hidden (actually,
|
|
whatever "dragging" state the script defines) instead of the usual
|
|
hilite.
|
|
|
|
************************************************************ PETED ***********/
|
|
void SCRT::_SetSelectionVis(bool fShow, bool fHideSel)
|
|
{
|
|
if (_iscenCur < _iscenMac && FIn(_iscenCur - _iscenTop, 0, _cfrmPage))
|
|
{
|
|
PGOK pgok = (PGOK)vapp.Pkwa()->PgobFromHid(_KidFromIscen(_iscenCur));
|
|
|
|
if (pgok != pvNil)
|
|
{
|
|
long lwState;
|
|
|
|
Assert(pgok->FIs(kclsGOK), "Didn't get a GOK GOB");
|
|
lwState = fShow ?
|
|
(fHideSel ? kstBrowserScrollingSel : kstBrowserSelected) :
|
|
kstBrowserEnabled;
|
|
if (pgok->Sno() != lwState)
|
|
pgok->FChangeState(lwState);
|
|
}
|
|
else
|
|
Bug("Where's my frame to select?");
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
_FResetThumbnails
|
|
Refills the thumbnails for the scenes frames. If the thumbnail
|
|
actually changed, force a redraw.
|
|
|
|
Arguments:
|
|
bool fHideSel -- fTrue if the current selection should be hidden
|
|
rather than highlighted
|
|
|
|
Returns: fTrue if it was successful in refilling the thumbnails
|
|
|
|
************************************************************ PETED ***********/
|
|
bool SCRT::_FResetThumbnails(bool fHideSel)
|
|
{
|
|
bool fSuccess = fFalse;
|
|
long kidCur = _kidFrameMin - 1, kidFrameCur = _kidFrameMin;
|
|
long iscen = _iscenTop, cFrame = _cfrmPage;
|
|
long lwSelState = fHideSel ? kstBrowserScrollingSel : kstBrowserSelected;
|
|
PGOK pgokFrame;
|
|
PGOMP pgomp;
|
|
SCEND scend;
|
|
|
|
while (cFrame--)
|
|
{
|
|
bool fNewTransition;
|
|
PMBMP pmbmp;
|
|
RC rc;
|
|
|
|
pgokFrame = (PGOK)vapp.Pkwa()->PgobFromHid(kidFrameCur);
|
|
pgomp = GOMP::PgompFromHidScr(kidCur);
|
|
|
|
if (pgokFrame == pvNil || pgomp == pvNil)
|
|
{
|
|
Bug("Couldn't find thumbnail or its frame");
|
|
goto LFail;
|
|
}
|
|
Assert(pgomp->FIs(kclsGOMP), "Thumbnail GOB isn't a GOMP");
|
|
Assert(pgokFrame->FIs(kclsGOK), "Frame GOB isn't a GOK");
|
|
if (iscen < _iscenMac)
|
|
{
|
|
long lwStateNew;
|
|
|
|
_cmvi.pglscend->Get(iscen, &scend);
|
|
pmbmp = scend.pmbmp;
|
|
lwStateNew = (iscen == _iscenCur) ? lwSelState : kstBrowserEnabled;
|
|
if (pgokFrame->Sno() != lwStateNew &&
|
|
!pgokFrame->FChangeState(lwStateNew))
|
|
{
|
|
goto LFail;
|
|
}
|
|
|
|
fNewTransition = _FResetTransition(pgokFrame, scend.trans);
|
|
iscen++;
|
|
}
|
|
else
|
|
{
|
|
pmbmp = pvNil;
|
|
if (pgokFrame->Sno() != kstBrowserDisabled &&
|
|
!pgokFrame->FChangeState(kstBrowserDisabled))
|
|
{
|
|
goto LFail;
|
|
}
|
|
fNewTransition = fFalse;
|
|
}
|
|
if (pgomp->FSetMbmp(pmbmp) || fNewTransition)
|
|
pgokFrame->InvalRc(pvNil);
|
|
|
|
kidCur--;
|
|
kidFrameCur += _cgokFrame;
|
|
}
|
|
|
|
/* Fill in selection frame; do this outside of the above loop, since the
|
|
selection is not always actually within the range of displayed scene
|
|
frames. */
|
|
if (_iscenMac > 0)
|
|
{
|
|
_cmvi.pglscend->Get(_iscenCur, &scend);
|
|
pgokFrame = (PGOK)vapp.Pkwa()->PgobFromHid(kidFrameCur);
|
|
Assert(pgokFrame != pvNil, "Selection GOK is missing");
|
|
Assert(pgokFrame->FIs(kclsGOK), "Frame GOB isn't a GOK");
|
|
pgomp = GOMP::PgompFromHidScr(kidCur);
|
|
Assert(pgomp != pvNil, "Selection GOMP is missing");
|
|
_FResetTransition(pgokFrame, scend.trans);
|
|
pgomp->FSetMbmp(scend.pmbmp);
|
|
}
|
|
|
|
_EnableScroll();
|
|
|
|
fSuccess = fTrue;
|
|
|
|
LFail:
|
|
return fSuccess;
|
|
}
|
|
|
|
|
|
const TRANS SCRT::_mplwtrans[] =
|
|
{
|
|
transCut,
|
|
transDissolve,
|
|
transFadeToBlack,
|
|
transFadeToWhite,
|
|
};
|
|
#define kctrans (size(_mplwtrans) / size(_mplwtrans[0]))
|
|
|
|
|
|
/******************************************************************************
|
|
_FResetTransition
|
|
Updates the transition buttons for a given scene frame.
|
|
|
|
Arguments:
|
|
PGOK pgokPar -- the parent scene frame GOK
|
|
TRANS trans -- the transition state for this scene
|
|
|
|
Returns: fTrue if the scene has a new transition and the frame needs
|
|
to be updated
|
|
|
|
************************************************************ PETED ***********/
|
|
bool SCRT::_FResetTransition(PGOK pgokPar, TRANS trans)
|
|
{
|
|
bool fRedrawTrans = fFalse;
|
|
PGOK pgokTrans, pgokThumb;
|
|
long lwTrans = kctrans, lwThis = _LwFromTrans(trans);
|
|
long lwStateCur, lwStateNew;
|
|
|
|
pgokThumb = (PGOK)pgokPar->PgobFirstChild();
|
|
Assert(pgokThumb->FIs(kclsGOK), "First child wasn't a GOK");
|
|
pgokTrans = (PGOK)pgokThumb->PgobNextSib();
|
|
Assert(pgokTrans->FIs(kclsGOK), "Transition GOB isn't a GOK");
|
|
while (lwTrans--)
|
|
{
|
|
lwStateCur = pgokTrans->Sno();
|
|
lwStateNew = (lwTrans != lwThis) ? kstDefault : kstSelected;
|
|
if (lwStateCur != lwStateNew)
|
|
{
|
|
fRedrawTrans = fTrue;
|
|
pgokTrans->FChangeState(lwStateNew);
|
|
}
|
|
pgokTrans = (PGOK)pgokTrans->PgobNextSib();
|
|
Assert(pgokTrans == pvNil ||
|
|
pgokTrans->FIs(kclsGOK), "Transition GOB isn't a GOK");
|
|
}
|
|
|
|
return fRedrawTrans;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
_TransFromLw
|
|
Map a long word to a transition
|
|
|
|
Arguments:
|
|
long lwTrans -- the scene sorter index of the transition
|
|
|
|
Returns: the actual transition
|
|
|
|
************************************************************ PETED ***********/
|
|
TRANS SCRT::_TransFromLw(long lwTrans)
|
|
{
|
|
AssertIn(lwTrans, 0, kctrans);
|
|
|
|
return _mplwtrans[lwTrans];
|
|
}
|
|
|
|
/******************************************************************************
|
|
_LwFromTrans
|
|
Map a transition to the scene sorter long word
|
|
|
|
Arguments:
|
|
TRANS trans -- the transition
|
|
|
|
Returns: the scene sorter long
|
|
|
|
************************************************************ PETED ***********/
|
|
long SCRT::_LwFromTrans(TRANS trans)
|
|
{
|
|
long lw;
|
|
|
|
for (lw = 0; lw < kctrans; lw++)
|
|
if (_mplwtrans[lw] == trans)
|
|
break;
|
|
|
|
#ifdef DEBUG
|
|
if (lw == kctrans)
|
|
{
|
|
Bug("Invalid trans");
|
|
lw = 0;
|
|
}
|
|
#endif /* DEBUG */
|
|
|
|
return lw;
|
|
}
|
|
|
|
|
|
RTCLASS(GOMP)
|
|
|
|
#ifdef DEBUG
|
|
void GOMP::AssertValid(ulong grf)
|
|
{
|
|
GOMP_PAR::AssertValid(0);
|
|
AssertNilOrPo(_pmbmp, 0);
|
|
}
|
|
|
|
void GOMP::MarkMem(void)
|
|
{
|
|
AssertThis(0);
|
|
|
|
GOMP_PAR::MarkMem();
|
|
MarkMemObj(_pmbmp);
|
|
}
|
|
#endif /* DEBUG */
|
|
|
|
|
|
/******************************************************************************
|
|
GOMP
|
|
Constructor for the GOMP class.
|
|
|
|
Arguments:
|
|
PGCB pgcb -- Gob Creation Block to be passed to the parent class
|
|
PMBMP pmbmp -- the MBMP to use when drawing this GOMP
|
|
|
|
************************************************************ PETED ***********/
|
|
GOMP::GOMP(PGCB pgcb) : GOB(pgcb)
|
|
{
|
|
_pmbmp = pvNil;
|
|
AssertThis(0);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
PgompNew
|
|
Creates a GOMP as a child of the given parent. The new GOMP will
|
|
be exactly the same size as the parent, and will have the given hid.
|
|
|
|
Arguments:
|
|
PMBMP pmbmp -- the MBMP to draw as this GOMP
|
|
PGOB pgobPar -- the parent of this GOMP
|
|
long hid -- the hid (kid) of this GOMP
|
|
|
|
Returns: pointer to the GOMP if it succeeds, pvNil otherwise
|
|
|
|
************************************************************ PETED ***********/
|
|
PGOMP GOMP::PgompNew(PGOB pgobPar, long hid)
|
|
{
|
|
AssertPo(pgobPar, 0);
|
|
|
|
PGOMP pgomp = pvNil;
|
|
GCB gcb;
|
|
RC rcRel(0, 0, krelOne, krelOne);
|
|
|
|
gcb.Set(hid, pgobPar, fgobNil, kginDefault, pvNil, &rcRel);
|
|
|
|
pgomp = NewObj GOMP(&gcb);
|
|
|
|
if (pgomp != pvNil && pgobPar->FIs(kclsGOK))
|
|
{
|
|
PT pt;
|
|
RC rcAbs;
|
|
|
|
((GOK *)pgobPar)->GetPtReg(&pt);
|
|
pgomp->GetPos(&rcAbs, &rcRel);
|
|
rcAbs.Offset(-pt.xp, -pt.yp);
|
|
pgomp->SetPos(&rcAbs, &rcRel);
|
|
}
|
|
|
|
return pgomp;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
Draw
|
|
Draws the given GOMP
|
|
|
|
Arguments:
|
|
PGNV pgnv -- the graphics environment in which to draw
|
|
RC *prcClip -- the clipping rect; this is ignored
|
|
|
|
************************************************************ PETED ***********/
|
|
void GOMP::Draw(PGNV pgnv, RC *prcClip)
|
|
{
|
|
AssertThis(0);
|
|
AssertPo(pgnv, 0);
|
|
AssertVarMem(prcClip);
|
|
|
|
RC rc;
|
|
|
|
if (_pmbmp == pvNil)
|
|
return;
|
|
|
|
_pmbmp->GetRc(&rc);
|
|
rc.OffsetToOrigin();
|
|
pgnv->DrawMbmp(_pmbmp, &rc);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
FSetMbmp
|
|
Replaces the MBMP for this GOMP with the given MBMP.
|
|
|
|
Arguments:
|
|
PMBMP pmbmp -- pointer to the MBMP
|
|
|
|
Returns: fTrue if the new MBMP is different from the old one
|
|
|
|
************************************************************ PETED ***********/
|
|
bool GOMP::FSetMbmp(PMBMP pmbmp)
|
|
{
|
|
AssertNilOrPo(pmbmp, 0);
|
|
|
|
bool fRedraw = (_pmbmp != pmbmp);
|
|
|
|
ReleasePpo(&_pmbmp);
|
|
if (pmbmp != pvNil)
|
|
pmbmp->AddRef();
|
|
_pmbmp = pmbmp;
|
|
|
|
return fRedraw;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
PgompFromHidScr
|
|
Given an HID, return the GOMP with that hid
|
|
|
|
Arguments:
|
|
long hid -- the hid of the GOMP to find
|
|
|
|
Returns: pointer to the GOMP
|
|
|
|
************************************************************ PETED ***********/
|
|
PGOMP GOMP::PgompFromHidScr(long hid)
|
|
{
|
|
PGOMP pgomp;
|
|
|
|
pgomp = (PGOMP)vapp.Pkwa()->PgobFromHid(hid);
|
|
if (pgomp != pvNil)
|
|
Assert(pgomp->FIs(kclsGOMP), "GOB isn't a GOMP");
|
|
return pgomp;
|
|
}
|