netscape-revival
lib/mac/VText/V_PowerPlant_Mods/LSelectHandlerView.cp
// ===========================================================================
// LSelectHandlerView.cp ©1994 Metrowerks Inc. All rights reserved.
// ===========================================================================
#ifdef PowerPlant_PCH
#include PowerPlant_PCH
#endif
#include "LSelectHandlerView.h"
#include <LSelection.h>
#include <LEventHandler.h>
#include <PP_Messages.h>
#include <LClipboardTube.h>
#include <LTargeter.h>
#include <UDrawingState.h>
#include <UDrawingUtils.h>
#include <LWindow.h>
#include <UDesktop.h>
#include <StClasses.h>
#include <LStream.h>
#ifndef __DESK__
#include <Desk.h>
#endif
#pragma warn_unusedarg off
// ===========================================================================
// Maintenance
LSelectHandlerView::LSelectHandlerView()
{
mSelection = NULL;
mTargeter = NULL;
pTargeter = 0;
mScrollingUpdate = false;
}
LSelectHandlerView::LSelectHandlerView(LStream *inStream)
: LHandlerView(inStream)
{
mSelection = NULL;
mTargeter = NULL;
pTargeter = 0;
mScrollingUpdate = false;
#ifndef PP_No_ObjectStreaming
SetSelection(ReadStreamable<LSelection *>()(*inStream));
#else
Int32 dummy;
*inStream >> dummy;
Assert_(dummy == typeNull);
#endif
*inStream >> pTargeter;
}
LSelectHandlerView::LSelectHandlerView(LStream *inStream, Boolean inOldStyle)
: LHandlerView(inStream, inOldStyle)
// TEMPORARY Constructor
{
mSelection = NULL;
mTargeter = NULL;
mScrollingUpdate = false;
mOldSelectionInvalid = false;
pTargeter = 0;
}
LSelectHandlerView::~LSelectHandlerView()
{
mTargeter = NULL; // Subviews are automatically deleted
ReplaceSharable(mSelection, (LSelection *)NULL, this);
}
void LSelectHandlerView::FinishCreateSelf(void)
{
mOldSelectionInvalid = true;
if (mTargeter == NULL) {
switch (pTargeter) {
case -2: // for enclosing a scroller
{
LTargeter *aTargeter = new LTargeter();
aTargeter->AttachPane(GetSuperView());
aTargeter->AttachTarget(this);
SetTargeter(aTargeter);
break;
}
case -1:
{
LTargeter *aTargeter = new LTargeter();
aTargeter->AttachPane(this);
aTargeter->AttachTarget(this);
SetTargeter(aTargeter);
break;
}
}
}
LHandlerView::FinishCreateSelf();
MutateSelection(IsOnDuty()); // Initialize old mOldSelectionRgn
}
LSelection * LSelectHandlerView::GetSelection(void)
{
return mSelection;
}
void LSelectHandlerView::SetSelection(LSelection *inSelection)
{
if (mSelection)
mSelection->RemoveListener(this);
ReplaceSharable(mSelection, inSelection, this);
if (mSelection)
mSelection->AddListener(this);
MutateSelection(IsOnDuty());
}
// ===========================================================================
// Selection support...
void LSelectHandlerView::DrawSelf(void)
// perform your pre-selection drawing then inherit/call this method.
{
if (!mScrollingUpdate)
DrawSelfSelection();
// else
// let ScrollImageBy take care of it...
}
void LSelectHandlerView::DrawSelfSelection(void)
{
if (mOldSelectionInvalid) {
GetPresentHiliteRgn(IsOnDuty(), mOldSelectionRgn);
mOldSelectionInvalid = false;
}
URegions::Hilite(mOldSelectionRgn);
}
void LSelectHandlerView::ClickSelf(const SMouseDownEvent &inMouseDown)
{
FocusDraw();
if (IsActive() && !IsTarget() && !inMouseDown.delaySelect)
ShouldBeTarget();
LHandlerView::ClickSelf(inMouseDown);
}
void LSelectHandlerView::Click(
SMouseDownEvent &inMouseDown)
{
Boolean delaySelect = inMouseDown.delaySelect;
Boolean isNonTargetDrag;
Point localPt;
isNonTargetDrag = !IsTarget();
isNonTargetDrag = isNonTargetDrag && mEventHandler && mSelection;
if (isNonTargetDrag) {
localPt = inMouseDown.whereLocal;
PortToLocalPoint(localPt);
FocusDraw();
isNonTargetDrag = mSelection->PointInRepresentation(localPt);
// Conditional to allow picking of only already selected elements...
// otherwise selection could be changed w/o bringing a window to
// the foreground. That would be a Mac HI violation.
}
if (!isNonTargetDrag || !mEventHandler) {
LView::Click(inMouseDown);
} else {
FocusDraw();
// sort of LPane::Click(inMouseDown);
inMouseDown.delaySelect = true;
inMouseDown.whereLocal = localPt;
UpdateClickCount(inMouseDown);
if (ExecuteAttachments(msg_Click, &inMouseDown)) {
ClickSelf(inMouseDown);
Assert_(mEventHandler->GetEvtState() == evs_Maybe);
mEventHandler->Track();
if (!mEventHandler->LastMaybeDragDragged())
ShouldBeTarget();
}
}
}
void LSelectHandlerView::ShouldBeTarget(void)
{
LWindow *window = LWindow::FetchWindowObject(GetMacPort());
if (window) {
LCommander *presentTarget = GetTarget(),
*p = presentTarget;
Boolean windowHasTarget = false;
while (p) {
if (p == window) {
windowHasTarget = true;
break;
}
p = p->GetSuperCommander();
}
if (windowHasTarget) {
LCommander::SwitchTarget(this);
} else {
window->SetLatentSub(this);
}
}
}
// ===========================================================================
// LCommander things
Boolean LSelectHandlerView::HandleKeyPress(const EventRecord &inKeyEvent)
{
Boolean rval = false;
FocusDraw();
if (!mEventHandler || !mEventHandler->DoEvent(inKeyEvent))
rval = LCommander::HandleKeyPress(inKeyEvent);
return rval;
}
void LSelectHandlerView::BeTarget(void)
{
LCommander::BeTarget();
if (mTargeter)
mTargeter->ShowFocus();
FocusDraw();
MutateSelection(true);
}
void LSelectHandlerView::DontBeTarget(void)
{
LCommander::DontBeTarget();
if (mTargeter)
mTargeter->HideFocus();
FocusDraw();
MutateSelection(false);
}
void LSelectHandlerView::SetTargeter(LTargeter *inTargeter)
{
mTargeter = inTargeter;
}
Boolean LSelectHandlerView::ObeyCommand(
CommandT inCommand,
void* ioParam)
{
Boolean cmdHandled = true;
LAction *action = NULL;
if (inCommand == msg_TabSelect) {
// Want the command handled but don't want the selection changed.
cmdHandled = true;
} else if (!mSelection) {
FocusDraw();
cmdHandled = inheritCommander::ObeyCommand(inCommand, ioParam);
} else {
switch (inCommand) {
case cmd_Cut:
action = mSelection->MakeCutAction();
PostAnAction(action);
cmdHandled = true;
break;
case cmd_Copy:
action = mSelection->MakeCopyAction();
PostAnAction(action);
cmdHandled = true;
break;
case cmd_Paste:
action = mSelection->MakePasteAction();
PostAnAction(action);
cmdHandled = true;
break;
case cmd_Clear:
action = mSelection->MakeClearAction();
PostAnAction(action);
cmdHandled = true;
break;
default:
cmdHandled = inheritCommander::ObeyCommand(inCommand, ioParam);
break;
}
}
return cmdHandled;
}
void LSelectHandlerView::FindCommandStatus(
CommandT inCommand,
Boolean &outEnabled,
Boolean &outUsesMark,
Char16 &outMark,
Str255 outName)
{
switch (inCommand) {
case cmd_Copy:
case cmd_Clear:
case cmd_Cut:
case cmd_Paste:
case cmd_SelectAll:
outUsesMark = false;
outEnabled = false;
}
switch (inCommand) {
case cmd_Copy:
case cmd_Clear:
case cmd_Cut:
if (mSelection && mSelection->IsSubstantive())
outEnabled = true;
break;
case cmd_Paste:
if (mSelection) {
LClipboardTube tube;
FlavorType flavor;
flavor = mSelection->PickFlavorFrom(&tube);
if (flavor != typeNull)
outEnabled = true;
}
break;
// case cmd_SelectAll: // Must be done by overrider
default:
inheritCommander::FindCommandStatus(inCommand, outEnabled,
outUsesMark, outMark, outName);
break;
}
}
// ===========================================================================
// LCommander things
void LSelectHandlerView::ListenToMessage(MessageT inMessage, void *ioParam)
{
switch (inMessage) {
case msg_SelectionChanged:
{
SetUpdateCommandStatus(true);
FocusDraw();
MutateSelection(IsOnDuty());
break;
}
}
}
// ===========================================================================
// LSelection hiliting...
void LSelectHandlerView::GetPresentHiliteRgn(
Boolean inAsActive,
RgnHandle ioRegion,
Int16 inOriginH,
Int16 inOriginV)
{
ThrowIfNULL_(ioRegion);
if (mSelection) {
Point origin = {0, 0};
mSelection->MakeRegion(origin, &ioRegion);
// Clip to visible area...
Rect r;
if (CalcLocalFrameRect(r)) {
StRegion tempRgn(r);
SectRgn(ioRegion, tempRgn, ioRegion);
ThrowIfOSErr_(QDError());
}
if (!inAsActive)
URegions::MakeRegionOutline(ioRegion, &ioRegion);
if (inOriginH || inOriginV) {
origin.h = -inOriginH;
origin.v = -inOriginV;
URegions::Translate(ioRegion, origin);
}
} else {
URegions::MakeEmpty(ioRegion);
}
}
void LSelectHandlerView::MutateSelection(Boolean inAsActive)
{
FocusDraw();
StRegion tempRgn(mOldSelectionRgn.mRgn);
GetPresentHiliteRgn(inAsActive, mOldSelectionRgn);
mOldSelectionInvalid = false;
XorRgn(tempRgn, mOldSelectionRgn, tempRgn);
ThrowIfOSErr_(QDError());
URegions::Hilite(tempRgn);
}
void LSelectHandlerView::MoveBy(
Int32 inHorizDelta,
Int32 inVertDelta,
Boolean inRefresh)
{
mOldSelectionInvalid = true;
LHandlerView::MoveBy(inHorizDelta, inVertDelta, inRefresh);
}
void LSelectHandlerView::ResizeFrameBy(
Int16 inWidthDelta,
Int16 inHeightDelta,
Boolean inRefresh)
{
mOldSelectionInvalid = true;
LHandlerView::ResizeFrameBy(inWidthDelta, inHeightDelta, inRefresh);
OutOfFocus(this);
FocusDraw();
}
void LSelectHandlerView::ScrollImageBy(
Int32 inLeftDelta, // Pixels to scroll horizontally
Int32 inTopDelta, // Pixels to scroll vertically
Boolean inRefresh)
{
FocusDraw(); // for floating windows that obscure this view...
SectRgn(mOldSelectionRgn, UQDGlobals::GetCurrentPort()->visRgn, mOldSelectionRgn);
ThrowIfOSErr_(QDError());
SPoint32 oldPortOrigin; // Type is important to avoid truncation
// errors below.
oldPortOrigin.h = mPortOrigin.h;
oldPortOrigin.v = mPortOrigin.v;
{
StChange<Boolean> tempChange(&mScrollingUpdate, true);
LHandlerView::ScrollImageBy(inLeftDelta, inTopDelta, inRefresh);
}
FocusDraw();
if ( (mPortOrigin.h != (oldPortOrigin.h + inLeftDelta)) ||
(mPortOrigin.v != (oldPortOrigin.v + inTopDelta))
) {
// The Quickdraw coordinate system just got wrapped so...
//
// Convert: the old hilite rgn in the old coordinate system to...
// the old hilite rgn in the NEW coordinate system.
SPoint32 delta32;
Point delta;
delta32.h = mPortOrigin.h - (oldPortOrigin.h + inLeftDelta);
delta32.v = mPortOrigin.v - (oldPortOrigin.v + inTopDelta);
Assert_((min_Int16 <= delta.h) && (delta.h <= max_Int16));
Assert_((min_Int16 <= delta.v) && (delta.v <= max_Int16));
delta.h = delta32.h;
delta.v = delta32.v;
URegions::Translate(mOldSelectionRgn, delta);
}
if (inRefresh && (inLeftDelta || inTopDelta)) {
MutateSelection(IsOnDuty());
}
}