mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-21 09:49:14 +00:00
Landing of 4.5 changes to get more flexibility in how divided views are handled.
This commit is contained in:
parent
a976242cdd
commit
e50d502d30
@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "divview.h"
|
||||
#include "CDividerGrippyPane.h"
|
||||
|
||||
#include "resgui.h"
|
||||
#include "macutil.h"
|
||||
@ -30,13 +31,14 @@
|
||||
LDividedView::LDividedView( LStream* inStream )
|
||||
//-----------------------------------
|
||||
: LView( inStream )
|
||||
, fFirstView(nil)
|
||||
, fSecondView(nil)
|
||||
, mCollapseFirstByDragging(false)
|
||||
, mCollapseSecondByDragging(false)
|
||||
, mFirstPane(nil)
|
||||
, mSecondPane(nil)
|
||||
, mFeatureFlags(eNoFeatures)
|
||||
, mDividerPosBeforeCollapsing(100)
|
||||
{
|
||||
*inStream >> mFirstSubview >> mSecondSubview;
|
||||
sSettingUp = true;
|
||||
|
||||
*inStream >> mFirstSubviewID >> mSecondSubviewID;
|
||||
|
||||
*inStream >> mDivSize;
|
||||
*inStream >> mFirstIndent;
|
||||
@ -50,7 +52,9 @@ LDividedView::LDividedView( LStream* inStream )
|
||||
*inStream >> mSlidesHorizontally;
|
||||
}
|
||||
|
||||
//-----------------------------------
|
||||
Boolean LDividedView::sSettingUp;
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
LDividedView::~LDividedView()
|
||||
//-----------------------------------
|
||||
{
|
||||
@ -62,168 +66,347 @@ void LDividedView::FinishCreateSelf()
|
||||
{
|
||||
LView::FinishCreateSelf();
|
||||
|
||||
fFirstView = (LView*)this->FindPaneByID( mFirstSubview );
|
||||
fSecondView = (LView*)this->FindPaneByID( mSecondSubview );
|
||||
LBroadcaster* zapButton = dynamic_cast<LBroadcaster*>(GetZapButton());
|
||||
mFirstPane = FindPaneByID( mFirstSubviewID );
|
||||
mSecondPane = FindPaneByID( mSecondSubviewID );
|
||||
LPane* zapPane = GetZapButton();
|
||||
LBroadcaster* zapButton = dynamic_cast<LBroadcaster*>(zapPane);
|
||||
if (zapButton)
|
||||
{
|
||||
zapButton->AddListener(this);
|
||||
// Make sure the first pane can be collapsed
|
||||
Boolean collapseFirst, collapseSecond;
|
||||
GetCollapseByDragging(collapseFirst, collapseSecond);
|
||||
SetCollapseByDragging(true, collapseSecond);
|
||||
// Turn off any bindings. We do this ourselves
|
||||
SBooleanRect zapFrameBinding;
|
||||
zapPane->GetFrameBinding(zapFrameBinding);
|
||||
// NOTE THE FOLLOWING CONVENTION: THE TOP AND BOTTOM BINDINGS ARE USED
|
||||
// TO SET THE FEATURE FLAGS. THEN WE TURN OFF THE POWERPLANT BINDINGS.
|
||||
// This is because the entire button has to be moved, not just the
|
||||
// bottom or top edge of it. So we take over this different type of
|
||||
// binding ourselves.
|
||||
// By the way, we cannot call SetFeatureFlags here, because we don't
|
||||
// want the side-effect of positioning the zap button - we haven't
|
||||
// calculated the offset yet!
|
||||
if (zapFrameBinding.top)
|
||||
SetFeatureFlagBits(eBindZapButtonTopOrLeft);
|
||||
else if (zapFrameBinding.bottom)
|
||||
SetFeatureFlagBits(eBindZapButtonBottomOrRight);
|
||||
zapFrameBinding.left
|
||||
= zapFrameBinding.top
|
||||
= zapFrameBinding.left
|
||||
= zapFrameBinding.bottom
|
||||
= zapFrameBinding.right
|
||||
= false;
|
||||
zapPane->SetFrameBinding(zapFrameBinding);
|
||||
OrientZapButtonTriangles();
|
||||
}
|
||||
this->SyncFrameBindings();
|
||||
mDividerPosBeforeCollapsing = GetDividerPosition();
|
||||
}
|
||||
SyncFrameBindings();
|
||||
if (!IsFirstPaneCollapsed() && !IsSecondPaneCollapsed())
|
||||
mDividerPosBeforeCollapsing = GetDividerPosition();
|
||||
sSettingUp = false;
|
||||
} // LDividedView::FinishCreateSelf
|
||||
|
||||
//-----------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
LPane* LDividedView::GetZapButton()
|
||||
//-----------------------------------
|
||||
{
|
||||
return FindPaneByID('Zap!');
|
||||
}
|
||||
|
||||
//-----------------------------------
|
||||
void LDividedView::ToggleFirstPane()
|
||||
//-----------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
void LDividedView::DoZapAction()
|
||||
// If one pane is collapsed, restore it to the saved position.
|
||||
// Otherwise, zap it as specified by the feature flags.
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if ((mFeatureFlags & eZapClosesFirst) && (mFeatureFlags & eZapClosesSecond))
|
||||
{
|
||||
Assert_(false); // you shouldn't have set both!
|
||||
UnsetFeatureFlags(eZapClosesFirst);
|
||||
}
|
||||
Int16 delta;
|
||||
if (IsFirstPaneCollapsed())
|
||||
delta = 1; // at left, restore to center.
|
||||
else if (IsSecondPaneCollapsed())
|
||||
delta = -1; // at right, restore to center
|
||||
else
|
||||
delta = - GetDividerPosition(); // collapse left
|
||||
StValueChanger<Boolean> save(mCollapseFirstByDragging, true);
|
||||
ChangeDividerPosition(delta);
|
||||
}
|
||||
else if (mFeatureFlags & eZapClosesFirst)
|
||||
delta = - 16000; // collapse left
|
||||
else if (mFeatureFlags & eZapClosesSecond)
|
||||
{
|
||||
delta = 16000; // collapse second
|
||||
}
|
||||
FeatureFlags savedFlags = mFeatureFlags;
|
||||
try
|
||||
{
|
||||
SetFeatureFlagBits(eCollapseBothWaysByDragging);
|
||||
ChangeDividerPosition(delta);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
}
|
||||
mFeatureFlags = savedFlags;
|
||||
} // LDividedView::DoZapAction
|
||||
|
||||
//-----------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
void LDividedView::ListenToMessage(MessageT inMessage, void* /*ioParam*/)
|
||||
//-----------------------------------
|
||||
{
|
||||
if (inMessage == 'Zap!')
|
||||
ToggleFirstPane();
|
||||
}
|
||||
DoZapAction();
|
||||
} // LDividedView::ListenToMessage
|
||||
|
||||
//-----------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
void LDividedView::OnlySetFeatureFlags(FeatureFlags inFlags)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// Since this is a public function, we don't allow it to change private bits (eg,
|
||||
// the binding bits).
|
||||
Assert_(inFlags == (inFlags & ~ePrivateMask));
|
||||
mFeatureFlags = (FeatureFlags)(mFeatureFlags | (inFlags & ~ePrivateMask));
|
||||
OrientZapButtonTriangles();
|
||||
} // LDividedView::OnlySetFeatureFlags
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void LDividedView::SyncFrameBindings()
|
||||
//-----------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
SBooleanRect firstBindings;
|
||||
SBooleanRect secondBindings;
|
||||
|
||||
firstBindings.top = firstBindings.bottom = firstBindings.left = firstBindings.right = TRUE;
|
||||
secondBindings.top = secondBindings.bottom = secondBindings.left = secondBindings.right = TRUE;
|
||||
firstBindings.top = firstBindings.bottom =
|
||||
firstBindings.left = firstBindings.right = true;
|
||||
secondBindings.top = secondBindings.bottom =
|
||||
secondBindings.left = secondBindings.right = true;
|
||||
|
||||
if ( mSlidesHorizontally )
|
||||
firstBindings.right = FALSE;
|
||||
{
|
||||
if (IsSecondPaneCollapsed())
|
||||
secondBindings.left = false;
|
||||
else
|
||||
firstBindings.right = false;
|
||||
}
|
||||
else
|
||||
firstBindings.bottom = FALSE;
|
||||
{
|
||||
if (IsSecondPaneCollapsed())
|
||||
secondBindings.top = false;
|
||||
else
|
||||
firstBindings.bottom = false;
|
||||
}
|
||||
|
||||
fFirstView->SetFrameBinding( firstBindings );
|
||||
fSecondView->SetFrameBinding( secondBindings );
|
||||
}
|
||||
mFirstPane->SetFrameBinding( firstBindings );
|
||||
mSecondPane->SetFrameBinding( secondBindings );
|
||||
} // LDividedView::SyncFrameBindings
|
||||
|
||||
void LDividedView::PositionZapButton()
|
||||
{
|
||||
SDimension16 zapFrameSize;
|
||||
LPane* zapButton = GetZapButton();
|
||||
if (!zapButton)
|
||||
return;
|
||||
zapButton->GetFrameSize(zapFrameSize);
|
||||
SDimension16 firstFrameSize;
|
||||
fFirstView->GetFrameSize( firstFrameSize );
|
||||
if (mSlidesHorizontally)
|
||||
zapButton->PlaceInSuperFrameAt(
|
||||
firstFrameSize.width + mFirstIndent,
|
||||
(mFrameSize.height >> 1) - (zapFrameSize.height >> 1),
|
||||
FALSE );
|
||||
//----------------------------------------------------------------------------------------
|
||||
void LDividedView::SetZapFrame(
|
||||
SInt16 inZapWidth,
|
||||
SInt16 inDividerPosition, // relative to divided view's frame
|
||||
SInt16 inDividerLength,
|
||||
SInt16& ioZapLength,
|
||||
SInt32& ioZapOffsetLateral, // relative to divided view's frame
|
||||
SInt32& ioZapOffsetLongitudinal) // relative to divided view's frame
|
||||
|
||||
// This routine is here to combine two cases : horizontal and vertical sliding.
|
||||
// The cases are identical except for having to interchange "h" and "v", "width" and
|
||||
// "height". The solution is to provide this routine in "latitude"/"longitude"
|
||||
// coordinates.
|
||||
//
|
||||
// The Zap button is long and thin. "Lateral" means orthogonal to its long dimension,
|
||||
// and "longitudinal" means parallel to its long dimension.
|
||||
//
|
||||
// Other blocks of code in this class could share code in a similar way.
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
const SInt16 kPreferredZapSize = 150;
|
||||
const UInt16 zapIndent = inZapWidth;
|
||||
const UInt16 zapMaxSize = inDividerLength * 2 / 3;
|
||||
ioZapLength = kPreferredZapSize;
|
||||
if (ioZapLength > zapMaxSize)
|
||||
ioZapLength = zapMaxSize;
|
||||
ioZapOffsetLateral = inDividerPosition;
|
||||
if (mFeatureFlags & eBindZapButtonTopOrLeft)
|
||||
ioZapOffsetLongitudinal = zapIndent;
|
||||
else if (mFeatureFlags & eBindZapButtonBottomOrRight)
|
||||
ioZapOffsetLongitudinal = inDividerLength - ioZapLength - zapIndent;
|
||||
else
|
||||
zapButton->PlaceInSuperFrameAt(
|
||||
(mFrameSize.width >> 1) - (zapFrameSize.width >> 1),
|
||||
firstFrameSize.height + mFirstIndent,
|
||||
FALSE );
|
||||
|
||||
}
|
||||
ioZapOffsetLongitudinal = (inDividerLength >> 1) - (ioZapLength >> 1);
|
||||
} // LDividedView::SetZapFrame
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void LDividedView::PositionZapButton()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
LPane* zapButton = GetZapButton();
|
||||
if (!zapButton || !mFirstPane || !FocusDraw())
|
||||
return;
|
||||
|
||||
SDimension16 zapFrameSize;
|
||||
zapButton->GetFrameSize(zapFrameSize);
|
||||
|
||||
SDimension16 firstFrameSize;
|
||||
mFirstPane->GetFrameSize(firstFrameSize);
|
||||
|
||||
SPoint32 zapFrameLocation;
|
||||
|
||||
if (mSlidesHorizontally)
|
||||
{
|
||||
SetZapFrame(
|
||||
zapFrameSize.width,
|
||||
firstFrameSize.width + mFirstIndent,
|
||||
mFrameSize.height,
|
||||
zapFrameSize.height,
|
||||
zapFrameLocation.h,
|
||||
zapFrameLocation.v);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetZapFrame(
|
||||
zapFrameSize.height,
|
||||
firstFrameSize.height + mFirstIndent,
|
||||
mFrameSize.width,
|
||||
zapFrameSize.width,
|
||||
zapFrameLocation.v,
|
||||
zapFrameLocation.h);
|
||||
}
|
||||
zapButton->ResizeFrameTo(zapFrameSize.width, zapFrameSize.height, false);
|
||||
zapButton->PlaceInSuperFrameAt(zapFrameLocation.h, zapFrameLocation.v, false);
|
||||
} // LDividedView::PositionZapButton
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void LDividedView::SetSubPanes(
|
||||
LPane* inFirstPane,
|
||||
LPane* inSecondPane,
|
||||
Int32 inDividerPos,
|
||||
Boolean inRefresh)
|
||||
// After a rearrangement of the hierarchy, change the two subviews and reposition them.
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
mFirstPane = inFirstPane;
|
||||
mSecondPane = inSecondPane;
|
||||
|
||||
mFirstPane->PutInside(this);
|
||||
mSecondPane->PutInside(this);
|
||||
|
||||
Int32 secondFrameOffset = inDividerPos + mDivSize;
|
||||
Int32 firstFrameSize = inDividerPos - mFirstIndent;
|
||||
|
||||
StValueChanger<Boolean> setterUp(sSettingUp, true);
|
||||
if ( mSlidesHorizontally )
|
||||
{
|
||||
mFirstPane->ResizeFrameTo( firstFrameSize,
|
||||
mFrameSize.height - (mFirstIndent * 2 ),
|
||||
false );
|
||||
mSecondPane->ResizeFrameTo( mFrameSize.width - (secondFrameOffset + mSecondIndent),
|
||||
mFrameSize.height - (mSecondIndent * 2),
|
||||
false );
|
||||
|
||||
mFirstPane->PlaceInSuperFrameAt( mFirstIndent, mFirstIndent, false );
|
||||
mSecondPane->PlaceInSuperFrameAt(secondFrameOffset,
|
||||
mSecondIndent,
|
||||
false );
|
||||
}
|
||||
else
|
||||
{
|
||||
mFirstPane->ResizeFrameTo( mFrameSize.width - ( mFirstIndent * 2 ),
|
||||
firstFrameSize,
|
||||
false );
|
||||
mSecondPane->ResizeFrameTo( mFrameSize.width - ( mSecondIndent * 2 ),
|
||||
mFrameSize.height - (secondFrameOffset + mSecondIndent),
|
||||
false );
|
||||
|
||||
mFirstPane->PlaceInSuperFrameAt( mFirstIndent, mFirstIndent, false );
|
||||
mSecondPane->PlaceInSuperFrameAt(mSecondIndent,
|
||||
secondFrameOffset,
|
||||
false );
|
||||
}
|
||||
PositionZapButton();
|
||||
SyncFrameBindings();
|
||||
BroadcastMessage( msg_DividerChangedPosition, this );
|
||||
CBevelView::SubPanesChanged(this, inRefresh);
|
||||
} // LDividedView::SetSubPanes
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void LDividedView::PositionViews( Boolean willBeHoriz )
|
||||
{
|
||||
if ( mSlidesHorizontally == willBeHoriz )
|
||||
return;
|
||||
|
||||
this->FocusDraw();
|
||||
FocusDraw();
|
||||
|
||||
mSlidesHorizontally = willBeHoriz;
|
||||
SDimension16 firstFrameSize;
|
||||
fFirstView->GetFrameSize( firstFrameSize );
|
||||
if ( mSlidesHorizontally )
|
||||
mFirstPane->GetFrameSize( firstFrameSize );
|
||||
if ( !mSlidesHorizontally ) // ie, it did BEFORE
|
||||
{
|
||||
Int16 subpaneSize = ( mFrameSize.height - mDivSize ) / 2;
|
||||
|
||||
fFirstView->ResizeFrameTo( mFrameSize.width - ( mFirstIndent * 2 ),
|
||||
mFirstPane->ResizeFrameTo( mFrameSize.width - ( mFirstIndent * 2 ),
|
||||
subpaneSize - mFirstIndent,
|
||||
FALSE );
|
||||
fSecondView->ResizeFrameTo( mFrameSize.width - ( mSecondIndent * 2 ),
|
||||
mSecondPane->ResizeFrameTo( mFrameSize.width - ( mSecondIndent * 2 ),
|
||||
subpaneSize - mSecondIndent,
|
||||
FALSE );
|
||||
|
||||
fFirstView->PlaceInSuperFrameAt( mFirstIndent, mFirstIndent, FALSE );
|
||||
fSecondView->PlaceInSuperFrameAt( mSecondIndent,
|
||||
firstFrameSize.height + mFirstIndent + mDivSize,
|
||||
FALSE );
|
||||
mFirstPane->PlaceInSuperFrameAt(
|
||||
mFirstIndent, mFirstIndent, false );
|
||||
mSecondPane->PlaceInSuperFrameAt(mSecondIndent,
|
||||
firstFrameSize.height + mFirstIndent + mDivSize,
|
||||
false );
|
||||
}
|
||||
else
|
||||
{
|
||||
Int16 subpaneSize = ( mFrameSize.width - mDivSize ) / 2;
|
||||
|
||||
fFirstView->ResizeFrameTo( subpaneSize - mFirstIndent,
|
||||
mFirstPane->ResizeFrameTo( subpaneSize - mFirstIndent,
|
||||
mFrameSize.height - ( mFirstIndent * 2 ),
|
||||
FALSE );
|
||||
fSecondView->ResizeFrameTo( subpaneSize - mSecondIndent,
|
||||
mSecondPane->ResizeFrameTo( subpaneSize - mSecondIndent,
|
||||
mFrameSize.height - ( mSecondIndent * 2),
|
||||
FALSE );
|
||||
|
||||
fFirstView->PlaceInSuperFrameAt( mFirstIndent, mFirstIndent, FALSE );
|
||||
fSecondView->PlaceInSuperFrameAt( firstFrameSize.width + mFirstIndent + mDivSize,
|
||||
mSecondIndent,
|
||||
FALSE );
|
||||
mFirstPane->PlaceInSuperFrameAt( mFirstIndent, mFirstIndent, false );
|
||||
mSecondPane->PlaceInSuperFrameAt(
|
||||
firstFrameSize.width + mFirstIndent + mDivSize,
|
||||
mSecondIndent,
|
||||
false );
|
||||
}
|
||||
PositionZapButton();
|
||||
mSlidesHorizontally = willBeHoriz;
|
||||
this->SyncFrameBindings();
|
||||
SyncFrameBindings();
|
||||
BroadcastMessage( msg_DividerChangedPosition, this );
|
||||
CBevelView::SubPanesChanged(this, true);
|
||||
this->Refresh();
|
||||
Refresh();
|
||||
} // LDividedView::PositionViews
|
||||
|
||||
// ¥Êset whether we are vertical or horizontal
|
||||
//----------------------------------------------------------------------------------------
|
||||
void LDividedView::SetSlidesHorizontally( Boolean isHoriz )
|
||||
// ¥Êset whether we are vertical or horizontal
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if ( mSlidesHorizontally != isHoriz )
|
||||
this->PositionViews( isHoriz );
|
||||
}
|
||||
PositionViews( isHoriz );
|
||||
} // LDividedView::SetSlidesHorizontally
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
Int32 LDividedView::GetDividerPosition() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
Rect firstFrame;
|
||||
|
||||
GetSubpaneRect( (LView*)this, fFirstView, firstFrame );
|
||||
if ( this->GetSlidesHorizontally() )
|
||||
GetSubpaneRect( (LView*)this, mFirstPane, firstFrame );
|
||||
if ( GetSlidesHorizontally() )
|
||||
return firstFrame.right;
|
||||
else
|
||||
return firstFrame.bottom;
|
||||
}
|
||||
} // LDividedView::GetDividerPosition
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void LDividedView::CalcRectBetweenPanes( Rect& invRect )
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
Rect firstFrame;
|
||||
Rect secondFrame;
|
||||
|
||||
GetSubpaneRect( this, fFirstView, firstFrame );
|
||||
GetSubpaneRect( this, fSecondView, secondFrame );
|
||||
GetSubpaneRect( this, mFirstPane, firstFrame );
|
||||
GetSubpaneRect( this, mSecondPane, secondFrame );
|
||||
|
||||
this->CalcLocalFrameRect( invRect );
|
||||
CalcLocalFrameRect( invRect );
|
||||
|
||||
if ( mSlidesHorizontally )
|
||||
{
|
||||
@ -235,17 +418,19 @@ void LDividedView::CalcRectBetweenPanes( Rect& invRect )
|
||||
invRect.top = firstFrame.bottom;
|
||||
invRect.bottom = secondFrame.top;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void LDividedView::CalcDividerRect( Rect& outRect )
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
Rect firstFrame;
|
||||
Rect secondFrame;
|
||||
|
||||
GetSubpaneRect( this, fFirstView, firstFrame );
|
||||
GetSubpaneRect( this, fSecondView, secondFrame );
|
||||
GetSubpaneRect( this, mFirstPane, firstFrame );
|
||||
GetSubpaneRect( this, mSecondPane, secondFrame );
|
||||
|
||||
this->CalcLocalFrameRect( outRect );
|
||||
CalcLocalFrameRect( outRect );
|
||||
|
||||
if ( mSlidesHorizontally )
|
||||
{
|
||||
@ -265,16 +450,18 @@ void LDividedView::CalcDividerRect( Rect& outRect )
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void LDividedView::CalcLimitRect( Rect& lRect )
|
||||
// ¥ this is somewhat hackish, but this routine calculates the limit rect
|
||||
// for dragging -- the hackish part is that it looks at its subviews
|
||||
// pane IDs to see if they begin with a 'D' and if so, assumes they
|
||||
// are also LDividedViews, and then does limiting based on that
|
||||
// Well, I fixed this by using dynamic_cast - jrm 97/10/17
|
||||
void LDividedView::CalcLimitRect( Rect& lRect )
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
this->CalcLocalFrameRect( lRect );
|
||||
CalcLocalFrameRect( lRect );
|
||||
|
||||
LDividedView* other = dynamic_cast<LDividedView*>(fFirstView);
|
||||
LDividedView* other = dynamic_cast<LDividedView*>(mFirstPane);
|
||||
if (other)
|
||||
{
|
||||
if ( other->GetSlidesHorizontally() == mSlidesHorizontally )
|
||||
@ -287,7 +474,7 @@ void LDividedView::CalcLimitRect( Rect& lRect )
|
||||
local.v = other->GetDividerPosition();
|
||||
|
||||
other->LocalToPortPoint( local );
|
||||
this->PortToLocalPoint( local );
|
||||
PortToLocalPoint( local );
|
||||
|
||||
if ( mSlidesHorizontally )
|
||||
lRect.left = local.h;
|
||||
@ -296,7 +483,7 @@ void LDividedView::CalcLimitRect( Rect& lRect )
|
||||
}
|
||||
}
|
||||
|
||||
other = dynamic_cast<LDividedView*>(fSecondView);
|
||||
other = dynamic_cast<LDividedView*>(mSecondPane);
|
||||
if (other)
|
||||
{
|
||||
if ( other->GetSlidesHorizontally() == mSlidesHorizontally )
|
||||
@ -309,7 +496,7 @@ void LDividedView::CalcLimitRect( Rect& lRect )
|
||||
local.v = other->GetDividerPosition();
|
||||
|
||||
other->LocalToPortPoint( local );
|
||||
this->PortToLocalPoint( local );
|
||||
PortToLocalPoint( local );
|
||||
|
||||
if ( mSlidesHorizontally )
|
||||
lRect.right = local.h;
|
||||
@ -320,53 +507,57 @@ void LDividedView::CalcLimitRect( Rect& lRect )
|
||||
|
||||
if ( mSlidesHorizontally )
|
||||
{
|
||||
if (!mCollapseFirstByDragging)
|
||||
if (!(mFeatureFlags & eCollapseFirstByDragging))
|
||||
lRect.left += mMinFirstSize;
|
||||
if (!mCollapseSecondByDragging)
|
||||
if (!(mFeatureFlags & eCollapseSecondByDragging))
|
||||
lRect.right -= mMinSecondSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!mCollapseFirstByDragging)
|
||||
if (!(mFeatureFlags & eCollapseFirstByDragging))
|
||||
lRect.top += mMinFirstSize;
|
||||
if (!mCollapseSecondByDragging)
|
||||
if (!(mFeatureFlags & eCollapseSecondByDragging))
|
||||
lRect.bottom -= mMinSecondSize;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void LDividedView::CalcSlopRect( Rect& sRect )
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
LWindow* myWin;
|
||||
|
||||
myWin = LWindow::FetchWindowObject( this->GetMacPort() );
|
||||
myWin = LWindow::FetchWindowObject( GetMacPort() );
|
||||
if ( myWin )
|
||||
{
|
||||
myWin->CalcPortFrameRect( sRect );
|
||||
sRect = PortToLocalRect( this, sRect );
|
||||
}
|
||||
else
|
||||
this->CalcLocalFrameRect( sRect );
|
||||
CalcLocalFrameRect( sRect );
|
||||
// If we're allowed to drag/collapse, allow a drag beyond the frame
|
||||
if (mCollapseFirstByDragging)
|
||||
if ((mFeatureFlags & eCollapseFirstByDragging))
|
||||
if (mSlidesHorizontally)
|
||||
sRect.left -= 100;
|
||||
else
|
||||
sRect.top -= 100;
|
||||
else if (mCollapseSecondByDragging)
|
||||
else if ((mFeatureFlags & eCollapseSecondByDragging))
|
||||
if (mSlidesHorizontally)
|
||||
sRect.right += 100;
|
||||
else
|
||||
sRect.bottom += 100;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void LDividedView::ClickSelf( const SMouseDownEvent& inMouseDown )
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
Rect frame;
|
||||
|
||||
this->CalcRectBetweenPanes( frame );
|
||||
CalcRectBetweenPanes( frame );
|
||||
if ( PtInRect( inMouseDown.whereLocal, &frame ) )
|
||||
{
|
||||
this->FocusDraw();
|
||||
FocusDraw();
|
||||
if (GetClickCount() > 1)
|
||||
{
|
||||
// we don't necessarily want users double-clicking to close the pane.
|
||||
@ -374,64 +565,71 @@ void LDividedView::ClickSelf( const SMouseDownEvent& inMouseDown )
|
||||
// ListenToMessage('Zap!', this);
|
||||
return;
|
||||
}
|
||||
|
||||
// if the first pane is closed and dragging to open is turned off,
|
||||
|
||||
// if either pane is closed and dragging to open is turned off,
|
||||
// bail before we get to the dragging code.
|
||||
if ( !GetDividerPosition() && !CanExpandByDragging() )
|
||||
if ( (IsFirstPaneCollapsed() || IsSecondPaneCollapsed()) && !CanExpandByDragging() )
|
||||
return;
|
||||
|
||||
StRegion myRgn;
|
||||
this->CalcDividerRect( frame );
|
||||
CalcDividerRect( frame );
|
||||
::RectRgn( myRgn, &frame );
|
||||
|
||||
Rect lRect, sRect;
|
||||
this->CalcLimitRect( lRect );
|
||||
this->CalcSlopRect( sRect );
|
||||
CalcLimitRect( lRect );
|
||||
CalcSlopRect( sRect );
|
||||
|
||||
long result = ::DragGrayRgn( myRgn, inMouseDown.whereLocal,
|
||||
&lRect, &sRect,
|
||||
mSlidesHorizontally ? hAxisOnly : vAxisOnly, nil );
|
||||
long result = ::DragGrayRgn( myRgn, inMouseDown.whereLocal, &lRect, &sRect,
|
||||
mSlidesHorizontally ? hAxisOnly : vAxisOnly, nil );
|
||||
|
||||
Int16 delta = mSlidesHorizontally ? LoWord( result ) : HiWord( result );
|
||||
|
||||
if ( ( result == kOutsideSlop ) || ( delta == 0 ) )
|
||||
if (result == kOutsideSlop || delta == 0)
|
||||
return;
|
||||
|
||||
this->ChangeDividerPosition( delta );
|
||||
ChangeDividerPosition( delta );
|
||||
}
|
||||
}
|
||||
|
||||
#define SAVE_VERSION 28
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void LDividedView::SavePlace( LStream* inStream )
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
WriteVersionTag( inStream, SAVE_VERSION );
|
||||
|
||||
*inStream << mSlidesHorizontally;
|
||||
Int32 divPos = this->GetDividerPosition();
|
||||
Int32 divPos = GetDividerPosition();
|
||||
*inStream << divPos;
|
||||
*inStream << mDividerPosBeforeCollapsing;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void LDividedView::RestorePlace( LStream* inStream )
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if ( !ReadVersionTag( inStream, SAVE_VERSION ) )
|
||||
throw (OSErr)rcDBWrongVersion;
|
||||
|
||||
Int32 shouldBe;
|
||||
Boolean isHoriz;
|
||||
|
||||
*inStream >> isHoriz;
|
||||
this->PositionViews( isHoriz );
|
||||
Int32 divPos = this->GetDividerPosition();
|
||||
*inStream >> shouldBe;
|
||||
this->ChangeDividerPosition( shouldBe - divPos );
|
||||
*inStream >> mDividerPosBeforeCollapsing;
|
||||
}
|
||||
Boolean isSlidingHoriz;
|
||||
*inStream >> isSlidingHoriz;
|
||||
|
||||
//-----------------------------------
|
||||
Int32 shouldBeHere;
|
||||
*inStream >> shouldBeHere;
|
||||
|
||||
*inStream >> mDividerPosBeforeCollapsing;
|
||||
|
||||
PositionViews( isSlidingHoriz );
|
||||
|
||||
Int32 divPos = GetDividerPosition();
|
||||
if (shouldBeHere != divPos)
|
||||
ChangeDividerPosition( shouldBeHere - divPos );
|
||||
} // LDividedView::RestorePlace
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void LDividedView::PlaySound(ResIDT id)
|
||||
//-----------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// Play the swishing sound, if available
|
||||
SndListHandle soundH =
|
||||
@ -444,13 +642,20 @@ void LDividedView::PlaySound(ResIDT id)
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
Boolean LDividedView::PreferSounds()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
return false; // no sounds! no sounds!
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void LDividedView::ChangeDividerPosition( Int16 delta )
|
||||
// ¥ move the divider, resize the top/left pane, and
|
||||
// move the bottom/right one
|
||||
//-----------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
Int32 dividerPos = this->GetDividerPosition();
|
||||
Int32 dividerPos = GetDividerPosition();
|
||||
Int16 newPos = dividerPos + delta;
|
||||
Int16 frameBound // drag beyond which causes slam
|
||||
= mSlidesHorizontally ? mFrameSize.width : mFrameSize.height;
|
||||
@ -459,11 +664,13 @@ void LDividedView::ChangeDividerPosition( Int16 delta )
|
||||
Boolean showSecond = false;
|
||||
if (newPos > frameBound - mMinSecondSize)
|
||||
{
|
||||
if (mCollapseSecondByDragging)
|
||||
if ((mFeatureFlags & eCollapseSecondByDragging))
|
||||
{
|
||||
if (IsSecondPaneCollapsed() && delta <= 0)
|
||||
{
|
||||
// Uncollapse from right
|
||||
if (mDividerPosBeforeCollapsing >= frameBound)
|
||||
mDividerPosBeforeCollapsing = frameBound / 2;
|
||||
delta = mDividerPosBeforeCollapsing - dividerPos;
|
||||
showSecond = true;
|
||||
}
|
||||
@ -471,12 +678,12 @@ void LDividedView::ChangeDividerPosition( Int16 delta )
|
||||
{
|
||||
// Collapse to right
|
||||
delta = frameBound - mDivSize - dividerPos;
|
||||
fSecondView->Hide();
|
||||
mSecondPane->Hide();
|
||||
if (dividerPos == 0) // user dragged from one extreme to the other
|
||||
showFirst = true;
|
||||
else
|
||||
mDividerPosBeforeCollapsing = dividerPos;
|
||||
if (IsVisible())
|
||||
if (IsVisible() && PreferSounds())
|
||||
PlayClosingSound();
|
||||
}
|
||||
}
|
||||
@ -485,11 +692,13 @@ void LDividedView::ChangeDividerPosition( Int16 delta )
|
||||
}
|
||||
else if (newPos < mMinFirstSize)
|
||||
{
|
||||
if (mCollapseFirstByDragging)
|
||||
if ((mFeatureFlags & eCollapseFirstByDragging))
|
||||
{
|
||||
if (IsFirstPaneCollapsed() && delta >= 0)
|
||||
{
|
||||
// Uncollapse from left
|
||||
if (mDividerPosBeforeCollapsing >= frameBound)
|
||||
mDividerPosBeforeCollapsing = frameBound / 2;
|
||||
delta = mDividerPosBeforeCollapsing - dividerPos;
|
||||
showFirst = true;
|
||||
}
|
||||
@ -497,12 +706,12 @@ void LDividedView::ChangeDividerPosition( Int16 delta )
|
||||
{
|
||||
// Collapse to left
|
||||
delta = - dividerPos;
|
||||
fFirstView->Hide();
|
||||
mFirstPane->Hide();
|
||||
if (dividerPos == frameBound - mDivSize)
|
||||
showSecond = true; // user dragged from one extreme to the other
|
||||
else
|
||||
mDividerPosBeforeCollapsing = dividerPos;
|
||||
if (IsVisible())
|
||||
if (IsVisible() && PreferSounds())
|
||||
PlayClosingSound();
|
||||
}
|
||||
}
|
||||
@ -514,61 +723,109 @@ void LDividedView::ChangeDividerPosition( Int16 delta )
|
||||
else if (IsFirstPaneCollapsed() && delta >= 0)
|
||||
showFirst = true;
|
||||
|
||||
LPane* zapButton = GetZapButton();
|
||||
if ( mSlidesHorizontally )
|
||||
if (mSlidesHorizontally)
|
||||
{
|
||||
fFirstView->ResizeFrameBy( delta, 0, FALSE );
|
||||
fSecondView->MoveBy( delta, 0, FALSE );
|
||||
fSecondView->ResizeFrameBy( -delta, 0, FALSE );
|
||||
if (zapButton)
|
||||
zapButton->MoveBy(delta, 0, FALSE);
|
||||
mFirstPane->ResizeFrameBy( delta, 0, false );
|
||||
mSecondPane->MoveBy( delta, 0, false );
|
||||
mSecondPane->ResizeFrameBy( -delta, 0, false );
|
||||
}
|
||||
else
|
||||
{
|
||||
fFirstView->ResizeFrameBy( 0, delta, FALSE );
|
||||
fSecondView->MoveBy( 0, delta, FALSE );
|
||||
fSecondView->ResizeFrameBy( 0, -delta, FALSE );
|
||||
if (zapButton)
|
||||
zapButton->MoveBy(0, delta, FALSE);
|
||||
mFirstPane->ResizeFrameBy( 0, delta, false );
|
||||
mSecondPane->MoveBy( 0, delta, false );
|
||||
mSecondPane->ResizeFrameBy( 0, -delta, false );
|
||||
}
|
||||
SyncFrameBindings();
|
||||
|
||||
BroadcastMessage( msg_DividerChangedPosition, this );
|
||||
|
||||
if (showFirst)
|
||||
fFirstView->Show();
|
||||
mFirstPane->Show();
|
||||
if (showSecond)
|
||||
fSecondView->Show();
|
||||
mSecondPane->Show();
|
||||
CBevelView::SubPanesChanged(this, false);
|
||||
if ((showFirst || showSecond) && IsVisible())
|
||||
if ((showFirst || showSecond) && IsVisible() && PreferSounds())
|
||||
PlayOpeningSound();
|
||||
this->Refresh();
|
||||
|
||||
PositionZapButton();
|
||||
OrientZapButtonTriangles();
|
||||
Refresh();
|
||||
} // LDividedView::ChangeDividerPosition
|
||||
|
||||
void
|
||||
LDividedView::ResizeFrameBy(
|
||||
enum
|
||||
{
|
||||
kTriangleRight = 10000
|
||||
, kTriangleDown
|
||||
, kTriangleLeft
|
||||
, kTriangleUp
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void LDividedView::OrientZapButtonTriangles()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// no grippies for mozilla??? not yet at least, maybe for HTML area.
|
||||
#if 0
|
||||
CDividerGrippyPane* zapper = dynamic_cast<CDividerGrippyPane*>(GetZapButton());
|
||||
if (!zapper)
|
||||
return;
|
||||
if (IsFirstPaneCollapsed()
|
||||
|| ((mFeatureFlags & eZapClosesSecond) && !IsSecondPaneCollapsed()))
|
||||
zapper->SetTriangleIconID(mSlidesHorizontally ? kTriangleRight : kTriangleDown);
|
||||
else if (IsSecondPaneCollapsed()
|
||||
|| ((mFeatureFlags & eZapClosesFirst) && !IsFirstPaneCollapsed()))
|
||||
zapper->SetTriangleIconID(mSlidesHorizontally ? kTriangleLeft : kTriangleUp);
|
||||
#endif
|
||||
} // LDividedView::OrientZapButtonTriangles
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void LDividedView::ResizeFrameBy(
|
||||
Int16 inWidthDelta,
|
||||
Int16 inHeightDelta,
|
||||
Boolean inRefresh)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// The big flaw in this class is that the situations when the two subpanes change
|
||||
// have to be handled case by case. This is but another.
|
||||
LView::ResizeFrameBy(inWidthDelta, inHeightDelta, inRefresh);
|
||||
PositionZapButton();
|
||||
CBevelView::SubPanesChanged(this, inRefresh);
|
||||
if (sSettingUp)
|
||||
return;
|
||||
|
||||
if (mFirstPane
|
||||
&& GetDividerPosition() > (mSlidesHorizontally ?
|
||||
mFrameSize.width : mFrameSize.height) - mDivSize)
|
||||
{
|
||||
// Bug #309526. The divider is bound to the left/top. If the second pane is
|
||||
// hidden, then it is bound to the right/bottom also. But if the second pane
|
||||
// is showing, and the window is sized too small by dragging the grow box,
|
||||
// then the divider can be out of view (not quite correct)! The real problem
|
||||
// with this is that the scrollbar can be clipped.
|
||||
// So if after the resize this situation obtains, make the following call.
|
||||
// ChangeDividerPosition will notice that the divider is offscreen,
|
||||
// and it will zap the second frame closed, so now the divider will stick to
|
||||
// the edge.
|
||||
ChangeDividerPosition(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
PositionZapButton();
|
||||
CBevelView::SubPanesChanged(this, inRefresh);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void LDividedView::AdjustCursorSelf( Point inPortPt, const EventRecord& inMacEvent )
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
Rect frame;
|
||||
|
||||
// if the pane is closed and drag-to-expand is turned off, bail.
|
||||
if ( !GetDividerPosition() && !CanExpandByDragging() )
|
||||
return;
|
||||
|
||||
this->CalcRectBetweenPanes( frame );
|
||||
this->PortToLocalPoint( inPortPt );
|
||||
CalcRectBetweenPanes( frame );
|
||||
PortToLocalPoint( inPortPt );
|
||||
if ( PtInRect( inPortPt, &frame ) )
|
||||
{
|
||||
// if either pane is closed and dragging to open is turned off,
|
||||
// bail before we get to cursor switching code
|
||||
if ( (IsFirstPaneCollapsed() || IsSecondPaneCollapsed()) && !CanExpandByDragging() )
|
||||
return;
|
||||
|
||||
if ( mSlidesHorizontally )
|
||||
::SetCursor( *(::GetCursor( curs_HoriDrag ) ) );
|
||||
else
|
||||
|
@ -28,12 +28,41 @@ const MessageT msg_DividerChangedPosition = 'divc';
|
||||
|
||||
class LDividedView :
|
||||
public LView,
|
||||
public LBroadcaster,
|
||||
public LListener
|
||||
public LBroadcaster, // broadcasts msg_DividerChangedPosition
|
||||
public LListener // Listens to Zap button (if any)
|
||||
{
|
||||
public:
|
||||
enum {class_ID = 'DIVV'};
|
||||
|
||||
enum FeatureFlags
|
||||
{
|
||||
eNoFeatures = 0
|
||||
, eCollapseFirstByDragging = (1<<0)
|
||||
, eCollapseSecondByDragging = (1<<1)
|
||||
, eZapClosesFirst = (1<<2)
|
||||
, eZapClosesSecond = (1<<3)
|
||||
, eBindZapButtonBottomOrRight = (1<<4) // if neither of these....
|
||||
, eBindZapButtonTopOrLeft = (1<<5) // ... then we center it.
|
||||
, eNoOpenByDragging = (1<<6)
|
||||
// Handy combinations
|
||||
, eCollapseBothWaysByDragging =
|
||||
(eCollapseFirstByDragging|eCollapseSecondByDragging)
|
||||
, eCollapseBothZapFirst =
|
||||
(eCollapseBothWaysByDragging|eZapClosesFirst)
|
||||
, eCollapseBothZapSecond =
|
||||
(eCollapseBothWaysByDragging|eZapClosesSecond)
|
||||
, eOnlyFirstIsCollapsible =
|
||||
(eZapClosesFirst|eCollapseFirstByDragging)
|
||||
, eOnlySecondIsCollapsible =
|
||||
(eZapClosesSecond|eCollapseSecondByDragging)
|
||||
// The bindings are set using the PP binding
|
||||
// fields in the PP constructor resource:
|
||||
, eBindingMask =
|
||||
(eBindZapButtonBottomOrRight|eBindZapButtonTopOrLeft)
|
||||
// Bits in this mask are not changeable through the public
|
||||
// SetFeatureFlags calls:
|
||||
, ePrivateMask =
|
||||
(eBindingMask)
|
||||
};
|
||||
LDividedView( LStream* inStream );
|
||||
virtual ~LDividedView();
|
||||
|
||||
@ -42,7 +71,7 @@ public:
|
||||
void SetSlidesHorizontally( Boolean isHoriz );
|
||||
Boolean GetSlidesHorizontally() const { return mSlidesHorizontally; };
|
||||
UInt16 GetDividerSize() const { return mDivSize; }
|
||||
void ToggleFirstPane();
|
||||
void DoZapAction();
|
||||
|
||||
virtual void ListenToMessage(MessageT inMessage, void* ioParam);
|
||||
|
||||
@ -58,23 +87,57 @@ public:
|
||||
virtual void SavePlace( LStream* inStream );
|
||||
virtual void RestorePlace( LStream* inStream );
|
||||
|
||||
void SetCollapseByDragging(Boolean inFirst, Boolean inSecond)
|
||||
{ mCollapseFirstByDragging = inFirst; mCollapseSecondByDragging = inSecond; }
|
||||
void GetCollapseByDragging(Boolean& outFirst, Boolean& outSecond)
|
||||
{ outFirst = mCollapseFirstByDragging; outSecond = mCollapseSecondByDragging; }
|
||||
|
||||
// These reposition things as necessary. But the bindings are private.
|
||||
void OnlySetFeatureFlags(FeatureFlags inFlags); // adjusts positions etc.
|
||||
void SetFeatureFlags(FeatureFlags inFlags) // adjusts positions etc.
|
||||
{ OnlySetFeatureFlags((FeatureFlags)(mFeatureFlags | inFlags)); }
|
||||
void UnsetFeatureFlags(FeatureFlags inFlags)
|
||||
{ OnlySetFeatureFlags((FeatureFlags)(mFeatureFlags & ~inFlags)); }
|
||||
|
||||
Boolean IsSecondPaneCollapsed() const
|
||||
{ return GetDividerPosition() >= (mSlidesHorizontally ? mFrameSize.width : mFrameSize.height) - mDivSize; }
|
||||
{ return GetDividerPosition() >= (mSlidesHorizontally ?
|
||||
mFrameSize.width : mFrameSize.height) - mDivSize; }
|
||||
Boolean IsFirstPaneCollapsed() const
|
||||
{ return GetDividerPosition() <= 0; }
|
||||
void SetSubPanes(
|
||||
LPane* inFirstPane,
|
||||
LPane* inSecondPane,
|
||||
Int32 inDividerPos,
|
||||
Boolean inRefresh);
|
||||
void GetSubPanes(
|
||||
LPane*& outFirstPane,
|
||||
LPane*& outSecondPane) const
|
||||
{ outFirstPane = mFirstPane; outSecondPane = mSecondPane; }
|
||||
Int32 GetDividerPosition() const;
|
||||
// WARNING: this does not access a stored value, it is
|
||||
// calculated by looking at the first subpane's current size.
|
||||
// It doesn't work too well if the first subpane is nil, or
|
||||
// if the first subpane has not yet been installed.
|
||||
|
||||
|
||||
static Boolean PreferSounds();
|
||||
static void PlayClosingSound() { PlaySound(128); }
|
||||
static void PlayOpeningSound() { PlaySound(129); }
|
||||
static void PlaySound(ResIDT id);
|
||||
|
||||
protected:
|
||||
|
||||
LPane* GetZapButton();
|
||||
void PositionZapButton();
|
||||
Int32 GetDividerPosition() const;
|
||||
void OrientZapButtonTriangles();
|
||||
void SetZapFrame(
|
||||
SInt16 inZapWidth,
|
||||
SInt16 inDividerPosition, // rel. to div view's frame
|
||||
SInt16 inDividerLength,
|
||||
SInt16& ioZapLength,
|
||||
SInt32& ioZapOffsetLateral, // rel. to div view's frame
|
||||
SInt32& ioZapOffsetLongitudinal); // rel. to div view's frame
|
||||
|
||||
// These two have no side-effects, and work on all bits.
|
||||
void SetFeatureFlagBits(FeatureFlags inFlags) // no other effects
|
||||
{ mFeatureFlags = (FeatureFlags)(mFeatureFlags | inFlags); }
|
||||
void UnsetFeatureFlagBits(FeatureFlags inFlags) // no other effects
|
||||
{ mFeatureFlags = (FeatureFlags)(mFeatureFlags & (~inFlags)); }
|
||||
|
||||
// ¥Êthe area representing the divider rect (only when dragging)
|
||||
void CalcDividerRect( Rect& outRect );
|
||||
@ -92,30 +155,31 @@ protected:
|
||||
// ¥Êthis routine is called to invalidate the rectangle between
|
||||
// the two panes (which is larger than divider rect) when
|
||||
// the divider is moved
|
||||
void CalcRectBetweenPanes( Rect& rect );
|
||||
|
||||
// ¥ allows the user to drag the closed pane to open it.
|
||||
bool CanExpandByDragging ( ) const { return false; } ;
|
||||
void CalcRectBetweenPanes( Rect& rect );
|
||||
|
||||
// ¥ check if we're allowed to pull out a collapsed pane by dragging
|
||||
virtual bool CanExpandByDragging ( ) const { return !(mFeatureFlags & eNoOpenByDragging); };
|
||||
|
||||
// Data
|
||||
protected:
|
||||
|
||||
PaneIDT mFirstSubview; // pane ID of the top or left pane
|
||||
PaneIDT mSecondSubview; // pane ID of the bottom or right pane
|
||||
PaneIDT mFirstSubviewID; // pane ID of the top or left pane
|
||||
PaneIDT mSecondSubviewID; // pane ID of the bottom or right pane
|
||||
|
||||
UInt16 mDivSize; // Width of the divider
|
||||
Int16 mMinFirstSize; // mimimum size of top (or left) pane
|
||||
Int16 mMinSecondSize; // minimum size of bottom (or right) pane
|
||||
|
||||
Boolean mCollapseFirstByDragging;
|
||||
Boolean mCollapseSecondByDragging;
|
||||
FeatureFlags mFeatureFlags;
|
||||
Int16 mDividerPosBeforeCollapsing;
|
||||
|
||||
Int16 mFirstIndent;
|
||||
Int16 mSecondIndent;
|
||||
|
||||
Boolean mSlidesHorizontally; // top/bottom or left/right configuration?
|
||||
Boolean mSlidesHorizontally;// top/bottom or left/right configuration?
|
||||
|
||||
LPane* fFirstView; // top or left view
|
||||
LPane* fSecondView; // bottom or right view
|
||||
LPane* mFirstPane; // top or left view
|
||||
LPane* mSecondPane; // bottom or right view
|
||||
|
||||
static Boolean sSettingUp;
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user