Getting the button class drawing and showing rollover feedback.

This commit is contained in:
pinkerton%netscape.com 1998-10-05 18:47:21 +00:00
Родитель c01c823a72
Коммит c5b5342df7
2 изменённых файлов: 402 добавлений и 12 удалений

Просмотреть файл

@ -28,9 +28,18 @@
//
#include "CRDFToolbarItem.h"
#include "CToolbarModeManager.h"
#include "UGraphicGizmos.h"
#include "UGAAppearance.h"
CRDFToolbarItem :: CRDFToolbarItem ( )
extern RDF_NCVocab gNavCenter; // RDF vocab struct for NavCenter
CRDFToolbarItem :: CRDFToolbarItem ( HT_Resource inNode )
: mNode(inNode)
{
Assert_(mNode != NULL);
}
@ -43,10 +52,26 @@ CRDFToolbarItem :: ~CRDFToolbarItem ( )
}
// a strawman drawing routine for testing purposes only
void
CRDFToolbarItem :: DrawSelf ( )
{
Rect localRect;
CalcLocalFrameRect ( localRect );
::FrameRect ( &localRect );
}
#pragma mark -
CRDFPushButton :: CRDFPushButton ( )
CRDFPushButton :: CRDFPushButton ( HT_Resource inNode )
: CRDFToolbarItem(inNode), mTitleTraitsID(130), mCurrentMode(eTOOLBAR_TEXT_AND_ICONS),
mMouseInFrame(false), mTrackInside(false), mGraphicPadPixels(5), mTitlePadPixels(5),
mTitleAlignment(kAlignCenterBottom), mGraphicAlignment(kAlignCenterTop),
mOvalWidth(8), mOvalHeight(8)
{
DebugStr("\pCreating a CRDFPushButton");
@ -60,10 +85,314 @@ CRDFPushButton :: ~CRDFPushButton ( )
}
//
// CalcTitleFrame
//
// This calculates the bounding box of the title (if any). This is useful
// for both the string placement, as well as position the button graphic
// (again, if any).
//
// Note that this routine sets the text traits for the ensuing draw. If
// you override this method, make sure that you're doing the same.
//
void
CRDFPushButton :: CalcTitleFrame ( )
{
char* title = HT_GetNodeName(HTNode());
if ( !title || !*title )
return;
UTextTraits::SetPortTextTraits(mTitleTraitsID);
FontInfo theInfo;
::GetFontInfo(&theInfo);
mCachedTitleFrame.top = mCachedButtonFrame.top;
mCachedTitleFrame.left = mCachedButtonFrame.left;
mCachedTitleFrame.right = mCachedTitleFrame.left + ::StringWidth(LStr255(title));;
mCachedTitleFrame.bottom = mCachedTitleFrame.top + theInfo.ascent + theInfo.descent + theInfo.leading;;
if (mCurrentMode != eTOOLBAR_TEXT)
{
UGraphicGizmos::AlignRectOnRect(mCachedTitleFrame, mCachedButtonFrame, mTitleAlignment);
UGraphicGizmos::PadAlignedRect(mCachedTitleFrame, mTitlePadPixels, mTitleAlignment);
}
else
{
UGraphicGizmos::CenterRectOnRect(mCachedTitleFrame, mCachedButtonFrame);
}
}
//
// CalcGraphicFrame
//
//
void
CRDFPushButton :: CalcGraphicFrame ( )
{
// The container for the graphic starts out as the whole
// button area.
Rect theContainerFrame = mCachedButtonFrame;
Rect theImageFrame = theContainerFrame;
UGraphicGizmos::AlignRectOnRect(theImageFrame, theContainerFrame, mGraphicAlignment);
UGraphicGizmos::PadAlignedRect(theImageFrame, mGraphicPadPixels, mGraphicAlignment);
mCachedGraphicFrame = theImageFrame;
}
//
// PrepareDrawButton
//
// Sets up frames and masks before we draw
//
void
CRDFPushButton :: PrepareDrawButton( )
{
CalcLocalFrameRect(mCachedButtonFrame);
// Calculate the drawing mask region.
::OpenRgn();
::FrameRoundRect(&mCachedButtonFrame, mOvalWidth, mOvalHeight);
::CloseRgn(mButtonMask);
CalcTitleFrame();
CalcGraphicFrame();
}
//
// FinalizeDrawButton
//
// Called after we are done drawing.
//
void
CRDFPushButton :: FinalizeDrawButton ( )
{
// nothing for now.
}
void
CRDFPushButton::DrawSelf()
{
PrepareDrawButton();
DrawButtonContent();
const char* title = HT_GetNodeName(HTNode());
if ( title ) {
if (mCurrentMode != eTOOLBAR_ICONS && *title != 0)
DrawButtonTitle();
}
if (mCurrentMode != eTOOLBAR_TEXT)
DrawButtonGraphic();
if (!IsEnabled() || !IsActive())
DrawSelfDisabled();
FinalizeDrawButton();
}
//
// DrawButtonContent
//
// Handle drawing things other than the graphic or title. For instance, if the
// mouse is within this frame, draw a border around the button. If the mouse is
// down, draw the button to look depressed.
//
void
CRDFPushButton :: DrawButtonContent ( )
{
if (IsActive() && IsEnabled()) {
if ( IsTrackInside() )
DrawButtonHilited();
else if (IsMouseInFrame())
DrawButtonOutline();
}
} // DrawButtonContent
//
// DrawButtonTitle
//
// Draw the title of the button.
//
void
CRDFPushButton :: DrawButtonTitle ( )
{
StColorPenState::Normalize();
if (IsTrackInside() || GetValue() == Button_On)
::OffsetRect(&mCachedTitleFrame, 1, 1);
char* title = HT_GetNodeName(HTNode());
UGraphicGizmos::PlaceStringInRect(LStr255(title), mCachedTitleFrame, teCenter, teCenter);
} // DrawButtonTitle
//
// DrawButtonGraphic
//
// Draw the image specified by HT.
// ¥¥¥If there isn't an image, what should we do
//
void
CRDFPushButton :: DrawButtonGraphic ( )
{
char* url = NULL;
PRBool success = HT_GetTemplateData ( HTNode(), gNavCenter->RDF_largeIcon, HT_COLUMN_STRING, &url );
if ( success && url ) {
// setup where we should draw
Point topLeft;
topLeft.h = mCachedGraphicFrame.left; topLeft.v = mCachedGraphicFrame.top;
uint16 width = mCachedGraphicFrame.right - mCachedGraphicFrame.left;
uint16 height = mCachedGraphicFrame.bottom - mCachedGraphicFrame.top;
// draw
SetImageURL ( url );
DrawImage ( topLeft, kTransformNone, width, height );
}
} // DrawButtonGraphic
void
CRDFPushButton :: DrawSelfDisabled ( )
{
// ??
} // DrawSelfDisabled
//
// DrawButtonOutline
//
// Draw the frame around the button to show rollover feedback
//
void
CRDFPushButton :: DrawButtonOutline ( )
{
// ¥ Setup a device loop so that we can handle drawing at the correct bit depth
StDeviceLoop theLoop ( mCachedButtonFrame );
Int16 depth;
// Draw face of button first
while ( theLoop.NextDepth ( depth ))
if ( depth >= 4 ) // don't do anything for black and white
{
Rect rect = mCachedButtonFrame;
::InsetRect(&rect, 1, 1);
UGraphicGizmos::LowerRoundRectColorVolume(rect, 4, 4,
UGAAppearance::sGAHiliteContentTint);
}
// Now draw GA button bevel
UGAAppearance::DrawGAButtonBevelTint(mCachedButtonFrame);
} // DrawButtonOutline
//
// DrawButtonHilited
//
// Draw the button as if it has been clicked on, drawing the insides depressed
//
void
CRDFPushButton :: DrawButtonHilited ( )
{
// ¥ Setup a device loop so that we can handle drawing at the correct bit depth
StDeviceLoop theLoop ( mCachedButtonFrame );
Int16 depth;
Rect frame = mCachedButtonFrame;
// Draw face of button first
while ( theLoop.NextDepth ( depth ))
if ( depth >= 4 ) // don't do anything for black and white
{
::InsetRect(&frame, 1, 1);
// Do we need to do this very slight darkening?
UGraphicGizmos::LowerRoundRectColorVolume(frame, 4, 4, UGAAppearance::sGASevenGrayLevels);
::InsetRect(&frame, -1, -1);
}
// Now draw GA pressed button bevel
UGAAppearance::DrawGAButtonPressedBevelTint(mCachedButtonFrame);
}
//
// ImageIsReady
//
// Called when the icon is ready to draw so we can refresh accordingly.
//
void
CRDFPushButton :: ImageIsReady ( )
{
Refresh(); // for now.
} // ImageIsReady
//
// DrawStandby
//
// Called when the image we want to draw has not finished loading. We get
// called to draw something in its place. Any good ideas?
void
CRDFPushButton :: DrawStandby ( const Point & inTopLeft, IconTransformType inTransform ) const
{
::FrameRect ( &mCachedGraphicFrame ); //¥¥¥ this is wrong!
} // DrawStandby
void
CRDFPushButton :: MouseEnter ( Point /*inPortPt*/, const EventRecord & /*inMacEvent*/ )
{
mMouseInFrame = true;
if (IsActive() && IsEnabled())
Draw(NULL);
}
void
CRDFPushButton :: MouseWithin ( Point /*inPortPt*/, const EventRecord & /*inMacEvent*/ )
{
// Nothing to do for now
}
void
CRDFPushButton :: MouseLeave( )
{
mMouseInFrame = false;
if (IsActive() && IsEnabled()) {
// since we can't simply draw the border w/ xor, we need to get the toolbar
// to redraw its bg and then redraw the normal button over it. To do this
// we create a rgn (in port coords), make it the clip rgn, and then draw
// the parent toolbar and this button again.
Rect portRect;
CalcPortFrameRect(portRect);
StRegion buttonRgnPort(portRect);
StClipRgnState savedClip(buttonRgnPort);
GetSuperView()->Draw(NULL);
Draw(NULL);
}
}
#pragma mark -
CRDFSeparator :: CRDFSeparator ( )
CRDFSeparator :: CRDFSeparator ( HT_Resource inNode )
: CRDFToolbarItem(inNode)
{
DebugStr("\pCreating a CRDFSeparator");
@ -81,7 +410,8 @@ CRDFSeparator :: ~CRDFSeparator ( )
#pragma mark -
CRDFURLBar :: CRDFURLBar ( )
CRDFURLBar :: CRDFURLBar ( HT_Resource inNode )
: CRDFToolbarItem(inNode)
{
DebugStr("\pCreating a CRDFURLBar");

Просмотреть файл

@ -29,6 +29,9 @@
#pragma once
#include "htrdf.h"
#include "CImageIconMixin.h"
//
// class CRDFToolbarItem
@ -36,14 +39,23 @@
// The base class for things that go on toolbars. This is a virtual class
// and should never be instantiated by itself.
//
class CRDFToolbarItem
class CRDFToolbarItem : public LView
{
public:
protected:
HT_Resource HTNode ( ) { return mNode; }
const HT_Resource HTNode ( ) const { return mNode; }
virtual void DrawSelf ( ) ;
private:
HT_Resource mNode;
// don't instantiate one of these
CRDFToolbarItem ( ) ;
CRDFToolbarItem ( HT_Resource inNode ) ;
virtual ~CRDFToolbarItem ( ) ;
// items cannot be passed by value because they exist in 1-to-1
@ -59,15 +71,63 @@ private:
//
// It's a button, it's a slicer, it's a mulcher, it's a ....
//
class CRDFPushButton : public CRDFToolbarItem
class CRDFPushButton : public CRDFToolbarItem, public CImageIconMixin
{
public:
CRDFPushButton ( ) ;
CRDFPushButton ( HT_Resource inNode ) ;
virtual ~CRDFPushButton ( ) ;
void SetTrackInside(bool inInside) { mTrackInside = inInside; }
bool IsTrackInside() const { return mTrackInside; }
protected:
// computations for drawing text and icon
virtual void PrepareDrawButton ( ) ;
virtual void CalcGraphicFrame ( ) ;
virtual void CalcTitleFrame ( ) ;
virtual void FinalizeDrawButton ( ) ;
// handle actual drawing
virtual void DrawSelf ( ) ;
virtual void DrawButtonContent ( ) ;
virtual void DrawButtonTitle ( ) ;
virtual void DrawButtonGraphic ( ) ;
virtual void DrawSelfDisabled ( ) ;
virtual void DrawButtonOutline ( ) ;
virtual void DrawButtonHilited ( ) ;
// handle drawing icon as an image
virtual void ImageIsReady ( ) ;
virtual void DrawStandby ( const Point & inTopLeft, IconTransformType inTransform ) const ;
// handle rollover feedback
virtual void MouseEnter ( Point inPortPt, const EventRecord &inMacEvent) ;
virtual void MouseWithin ( Point inPortPt, const EventRecord &inMacEvent);
virtual void MouseLeave(void);
bool IsMouseInFrame ( ) const { return mMouseInFrame; } ;
private:
// items cannot be passed by value because they exist in 1-to-1 correspondance
// with UI elements
StRegion mButtonMask;
Rect mCachedButtonFrame;
Rect mCachedTitleFrame;
Rect mCachedGraphicFrame;
ResIDT mTitleTraitsID;
UInt8 mCurrentMode;
Int8 mGraphicPadPixels;
Int8 mTitlePadPixels;
Int8 mTitleAlignment;
Int8 mGraphicAlignment;
Uint8 mOvalWidth, mOvalHeight;
bool mMouseInFrame;
bool mTrackInside;
// items cannot be passed by value because they exist in 1-to-1
// correspondance with UI elements
CRDFPushButton( const CRDFPushButton& ); // DON'T IMPLEMENT
CRDFPushButton& operator=( const CRDFPushButton& ); // DON'T IMPLEMENT
@ -82,7 +142,7 @@ private:
class CRDFSeparator : public CRDFToolbarItem
{
public:
CRDFSeparator ( ) ;
CRDFSeparator ( HT_Resource inNode ) ;
virtual ~CRDFSeparator ( ) ;
private:
@ -102,7 +162,7 @@ private:
class CRDFURLBar : public CRDFToolbarItem
{
public:
CRDFURLBar ( ) ;
CRDFURLBar ( HT_Resource inNode ) ;
virtual ~CRDFURLBar ( ) ;
private: