387 lines
8.6 KiB
C++
387 lines
8.6 KiB
C++
/* Copyright (c) Microsoft Corporation.
|
|
Licensed under the MIT License. */
|
|
|
|
/***************************************************************************
|
|
|
|
popup.cpp: Popup menu classes
|
|
|
|
Primary Author: ******
|
|
MPFNT: ******
|
|
Review Status: REVIEWED - any changes to this file must be reviewed!
|
|
|
|
|
|
***************************************************************************/
|
|
#include "studio.h"
|
|
ASSERTNAME
|
|
|
|
RTCLASS(MP)
|
|
RTCLASS(MPFNT)
|
|
|
|
BEGIN_CMD_MAP(MP, BRWD)
|
|
ON_CID_GEN(cidSelIdle, FCmdSelIdle, pvNil)
|
|
END_CMD_MAP_NIL()
|
|
|
|
|
|
/***************************************************************************
|
|
Create a new popup menu
|
|
***************************************************************************/
|
|
PMP MP::PmpNew(long kidParent, long kidMenu, PRCA prca, PCMD pcmd,
|
|
BWS bws, long ithumSelect, long sidSelect, CKI ckiRoot, CTG ctg,
|
|
PCMH pcmh, long cid, bool fMoveTop)
|
|
{
|
|
AssertPo(prca, 0);
|
|
AssertVarMem(pcmd);
|
|
AssertPo(pcmh, 0);
|
|
|
|
PMP pmp;
|
|
GCB gcb;
|
|
PSTDIO pstdio;
|
|
long cthum;
|
|
long cfrm;
|
|
|
|
pstdio = vpapp->Pstdio();
|
|
if (pvNil == pstdio)
|
|
{
|
|
Bug("pstdio is nil");
|
|
return pvNil;
|
|
}
|
|
|
|
if (!_FBuildGcb(&gcb, kidParent, kidMenu))
|
|
return pvNil;
|
|
|
|
pmp = NewObj MP(&gcb);
|
|
if (pvNil == pmp)
|
|
goto LFail;
|
|
if (!pmp->_FInitGok(prca, kidMenu))
|
|
goto LFail;
|
|
if (!pmp->FInit(pcmd, bws, ithumSelect, sidSelect, ckiRoot,
|
|
ctg, pstdio, pvNil, fFalse, 1))
|
|
{
|
|
goto LFail;
|
|
}
|
|
|
|
//
|
|
// Add ourselves as a CMH with a high priority so that we can
|
|
// filter out SelIdle messages
|
|
//
|
|
if (!vpcex->FAddCmh(pmp, -1000))
|
|
{
|
|
goto LFail;
|
|
}
|
|
if (!pmp->FDraw())
|
|
goto LFail;
|
|
|
|
pmp->_cid = cid;
|
|
pmp->_pcmh = pcmh;
|
|
|
|
// Need to adjust the size if cthum <= cfrm
|
|
// New height should be dypTop + cthum * dypFrm + dypTop
|
|
cthum = pmp->_Cthum();
|
|
cfrm = pmp->_cfrm;
|
|
|
|
if (cthum <= cfrm)
|
|
{
|
|
PGOB pgob;
|
|
long dypFrm;
|
|
long dypTop;
|
|
RC rc;
|
|
RC rcAbs;
|
|
RC rcRel;
|
|
|
|
pgob = vpapp->Pkwa()->PgobFromHid(pmp->_kidFrmFirst);
|
|
AssertPo(pgob, 0);
|
|
pgob->GetRc(&rc, cooParent);
|
|
dypFrm = rc.Dyp();
|
|
dypTop = rc.ypTop;
|
|
pmp->GetPos(&rcAbs, &rcRel);
|
|
if (fMoveTop)
|
|
rcAbs.ypTop = rcAbs.ypBottom - (dypTop + LwMul(cthum, dypFrm) + dypTop);
|
|
else
|
|
rcAbs.ypBottom = rcAbs.ypTop + (dypTop + LwMul(cthum, dypFrm) + dypTop);
|
|
pmp->SetPos(&rcAbs, &rcRel);
|
|
}
|
|
AssertPo(pmp, 0);
|
|
return pmp;
|
|
LFail:
|
|
ReleasePpo(&pmp);
|
|
return pvNil;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Enqueue a cid saying what was selected
|
|
***************************************************************************/
|
|
void MP::_ApplySelection(long ithumSelect, long sid)
|
|
{
|
|
AssertThis(0);
|
|
|
|
if (_ckiRoot.ctg == kctgTyth)
|
|
{
|
|
THD thd;
|
|
|
|
_pglthd->Get(ithumSelect, &thd);
|
|
vpcex->EnqueueCid(_cid, _pcmh, pvNil, thd.grfontMask, thd.grfont);
|
|
return;
|
|
}
|
|
vpcex->EnqueueCid(_cid, _pcmh, pvNil, ithumSelect, sid);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
_IthumFromThum
|
|
Override the default BWRL routine so that we can map a font bitfield
|
|
to the proper ithum.
|
|
|
|
|
|
Arguments:
|
|
long thumSelect
|
|
long sidSelect
|
|
|
|
Returns:
|
|
|
|
Keywords:
|
|
|
|
************************************************************ PETED ***********/
|
|
long MP::_IthumFromThum(long thumSelect, long sidSelect)
|
|
{
|
|
AssertBaseThis(0);
|
|
|
|
long ithum;
|
|
|
|
if (_ckiRoot.ctg == kctgTyth)
|
|
{
|
|
THD thd;
|
|
|
|
ithum = _pglthd->IvMac();
|
|
while (ithum-- > 0)
|
|
{
|
|
_pglthd->Get(ithum, &thd);
|
|
if (thd.grfont == (thumSelect & thd.grfontMask))
|
|
break;
|
|
}
|
|
Assert(ithum >= 0 || ithum == ivNil, "Returning invalid ithum");
|
|
}
|
|
else
|
|
ithum = MP_PAR::_IthumFromThum(thumSelect, sidSelect);
|
|
return ithum;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Do selection idle processing. Make sure not to change any selection
|
|
states.
|
|
***************************************************************************/
|
|
bool MP::FCmdSelIdle(PCMD pcmd)
|
|
{
|
|
AssertThis(0);
|
|
AssertVarMem(pcmd);
|
|
|
|
MP_PAR::FCmdSelIdle(pcmd);
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
#ifdef DEBUG
|
|
/***************************************************************************
|
|
Assert the validity of the MP.
|
|
***************************************************************************/
|
|
void MP::AssertValid(ulong grf)
|
|
{
|
|
MP_PAR::AssertValid(fobjAllocated);
|
|
AssertBasePo(_pcmh, 0);
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Mark memory used by the MP
|
|
***************************************************************************/
|
|
void MP::MarkMem(void)
|
|
{
|
|
AssertThis(0);
|
|
MP_PAR::MarkMem();
|
|
MarkMemObj(_pcmh);
|
|
}
|
|
#endif //DEBUG
|
|
|
|
|
|
//
|
|
//
|
|
//
|
|
// MPFNT (font menu) stuff begins here
|
|
//
|
|
//
|
|
//
|
|
|
|
|
|
BEGIN_CMD_MAP(MPFNT, BRWD)
|
|
ON_CID_GEN(cidSelIdle, FCmdSelIdle, pvNil)
|
|
END_CMD_MAP_NIL()
|
|
|
|
/***************************************************************************
|
|
Create a new font menu
|
|
***************************************************************************/
|
|
PMPFNT MPFNT::PmpfntNew(PRCA prca, long kidParent, long kidMenu, PCMD pcmd,
|
|
long ithumSelect, PGST pgst)
|
|
{
|
|
AssertPo(prca, 0);
|
|
AssertVarMem(pcmd);
|
|
AssertPo(pgst, 0);
|
|
|
|
PMPFNT pmpfnt;
|
|
GCB gcb;
|
|
PSTDIO pstdio = vpapp->Pstdio();
|
|
|
|
if (pstdio == pvNil)
|
|
{
|
|
Bug("pstdio is nil");
|
|
return pvNil;
|
|
}
|
|
|
|
if (pgst->CbExtra() != size(long))
|
|
{
|
|
Bug("GST CbExtra isn't the right size for an onn");
|
|
return pvNil;
|
|
}
|
|
|
|
if (!_FBuildGcb(&gcb, kidParent, kidMenu))
|
|
return pvNil;
|
|
|
|
pmpfnt = NewObj MPFNT(&gcb);
|
|
if (pmpfnt == pvNil)
|
|
return pvNil;
|
|
|
|
pmpfnt->_pgst = pgst;
|
|
pmpfnt->_pgst->AddRef();
|
|
|
|
if (!pmpfnt->_FInitGok(prca, kidMenu))
|
|
goto LFail;
|
|
|
|
if (!pmpfnt->FInit(pcmd, ithumSelect, ithumSelect, pstdio, fFalse, 1))
|
|
goto LFail;
|
|
|
|
//
|
|
// Add ourselves as a CMH with a high priority so that we can
|
|
// filter out SelIdle messages
|
|
//
|
|
if (!vpcex->FAddCmh(pmpfnt, -1000))
|
|
{
|
|
goto LFail;
|
|
}
|
|
|
|
if (!pmpfnt->FDraw())
|
|
goto LFail;
|
|
pmpfnt->_AdjustRc(pmpfnt->_Cthum(), pmpfnt->_cfrm);
|
|
|
|
AssertPo(pmpfnt, 0);
|
|
return pmpfnt;
|
|
|
|
LFail:
|
|
ReleasePpo(&pmpfnt);
|
|
return pvNil;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Set the font of the TGOB to the font listed in the menu item
|
|
***************************************************************************/
|
|
bool MPFNT::_FSetThumFrame(long istn, PGOB pgobPar)
|
|
{
|
|
if (MPFNT_PAR::_FSetThumFrame(istn, pgobPar))
|
|
{
|
|
PTGOB ptgob = (PTGOB)pgobPar->PgobFirstChild();
|
|
long onn;
|
|
|
|
/* By the time we get this far, MPFNT_PAR should have already checked
|
|
these */
|
|
Assert(ptgob != pvNil, "No TGOB for the text");
|
|
Assert(ptgob->FIs(kclsTGOB), "GOB isn't a TGOB");
|
|
|
|
_pgst->GetExtra(istn, &onn);
|
|
ptgob->SetFont(onn);
|
|
ptgob->SetAlign(tahLeft, tavCenter);
|
|
return fTrue;
|
|
}
|
|
return fFalse;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Tell the studio that the font was selected
|
|
***************************************************************************/
|
|
void MPFNT::_ApplySelection(long ithumSelect, long sid)
|
|
{
|
|
AssertThis(0);
|
|
|
|
long onn;
|
|
|
|
_pgst->GetExtra(ithumSelect, &onn);
|
|
vpcex->EnqueueCid(cidTextSetFont, _pstdio, pvNil, onn);
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Hide the scroll arrows if necessary
|
|
***************************************************************************/
|
|
void MPFNT::_AdjustRc(long cthum, long cfrm)
|
|
{
|
|
PGOB pgob;
|
|
long dypFrm;
|
|
long dypTop;
|
|
RC rc;
|
|
RC rcAbs;
|
|
RC rcRel;
|
|
|
|
/* Still need to adjust if cthum == cfrm to hide scroll arrows */
|
|
if (cthum > cfrm)
|
|
return;
|
|
|
|
/* For the font popup, the GOBs that are interesting for adjusting the
|
|
entire browser are actually the parents of the thumbnail frames */
|
|
pgob = vapp.Pkwa()->PgobFromHid(_kidFrmFirst);
|
|
AssertPo(pgob, 0);
|
|
pgob = pgob->PgobPar();
|
|
AssertPo(pgob, 0);
|
|
pgob->GetRc(&rc, cooParent);
|
|
dypFrm = rc.Dyp();
|
|
dypTop = rc.ypTop;
|
|
|
|
GetPos(&rcAbs, &rcRel);
|
|
rcAbs.ypBottom = rcAbs.ypTop + (dypTop + LwMul(cthum, dypFrm) + dypTop);
|
|
SetPos(&rcAbs, &rcRel);
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Do selection idle processing. Make sure not to change any selection
|
|
states.
|
|
***************************************************************************/
|
|
bool MPFNT::FCmdSelIdle(PCMD pcmd)
|
|
{
|
|
AssertThis(0);
|
|
AssertVarMem(pcmd);
|
|
|
|
MPFNT_PAR::FCmdSelIdle(pcmd);
|
|
return fTrue;
|
|
}
|
|
|
|
|
|
#ifdef DEBUG
|
|
/***************************************************************************
|
|
Assert the validity of the MPFNT.
|
|
***************************************************************************/
|
|
void MPFNT::AssertValid(ulong grf)
|
|
{
|
|
MPFNT_PAR::AssertValid(0);
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Mark memory used by the MPFNT
|
|
***************************************************************************/
|
|
void MPFNT::MarkMem(void)
|
|
{
|
|
AssertThis(0);
|
|
MPFNT_PAR::MarkMem();
|
|
}
|
|
#endif //DEBUG
|