mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-16 15:17:14 +00:00
452 lines
12 KiB
C++
452 lines
12 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* The contents of this file are subject to the Netscape Public License
|
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
|
* http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
|
* for the specific language governing rights and limitations under the
|
|
* NPL.
|
|
*
|
|
* The Initial Developer of this code under the NPL is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
|
* Reserved.
|
|
*/
|
|
|
|
/* Portions copyright Metrowerks Corporation. */
|
|
|
|
#include "CSizePopup.h"
|
|
|
|
#include "PascalString.h"
|
|
#include "uerrmgr.h"
|
|
#include "resgui.h"
|
|
#include "macutil.h"
|
|
#include "UModalDialogs.h"
|
|
#include "UGraphicGizmos.h"
|
|
|
|
#include <UNewTextDrawing.h>
|
|
#include <UGAColorRamp.h>
|
|
#include <UGraphicsUtilities.h>
|
|
|
|
static const Char16 gsPopup_SmallMark = '¥'; // Mark used for small font popups
|
|
static const Int16 gsPopup_ArrowButtonWidth = 22; // Width used in drawing the arrow only
|
|
static const Int16 gsPopup_ArrowButtonHeight = 16; // Height used for drawing arrow only
|
|
static const Int16 gsPopup_ArrowHeight = 5; // Actual height of the arrow
|
|
static const Int16 gsPopup_ArrowWidth = 9; // Actual width of the arrow at widest
|
|
|
|
//-----------------------------------
|
|
CSizePopup::CSizePopup(LStream* inStream)
|
|
//-----------------------------------
|
|
: mFontNumber(0)
|
|
, LGAPopup(inStream)
|
|
{
|
|
}
|
|
|
|
//-----------------------------------
|
|
Int32 CSizePopup::GetMenuSize() const
|
|
//-----------------------------------
|
|
{
|
|
Int32 size = 0;
|
|
MenuHandle menuH = const_cast<CSizePopup*>(this)->GetMacMenuH();
|
|
|
|
if (menuH)
|
|
{
|
|
size = ::CountMItems(menuH);
|
|
}
|
|
|
|
return size;
|
|
}
|
|
|
|
//-----------------------------------
|
|
void CSizePopup::SetUpCurrentMenuItem(MenuHandle inMenuH, Int16 inCurrentItem )
|
|
//-----------------------------------
|
|
{
|
|
|
|
// ¥ If the current item has changed then make it so, this
|
|
// also involves removing the mark from any old item
|
|
if (inMenuH)
|
|
{
|
|
CStr255 sizeString;
|
|
CStr255 itemString;
|
|
Handle ellipsisHandle = nil;
|
|
char ellipsisChar;
|
|
short menuSize = ::CountMItems(inMenuH);
|
|
|
|
ThrowIfNil_(ellipsisHandle = ::GetResource('elps', 1000));
|
|
|
|
ellipsisChar = **ellipsisHandle;
|
|
::ReleaseResource(ellipsisHandle);
|
|
|
|
if (inCurrentItem == ::CountMItems(inMenuH))
|
|
{
|
|
itemString = ::GetCString(OTHER_FONT_SIZE);
|
|
::StringParamText(itemString, (SInt32) GetFontSize(), 0, 0, 0);
|
|
}
|
|
else
|
|
{
|
|
itemString = ::GetCString(OTHER_RESID);
|
|
itemString += ellipsisChar;
|
|
}
|
|
|
|
::SetMenuItemText(inMenuH, menuSize, itemString);
|
|
|
|
// ¥ Get the current value
|
|
Int16 oldItem = GetValue();
|
|
|
|
// ¥ Remove the current mark
|
|
::SetItemMark(inMenuH, oldItem, 0);
|
|
|
|
// ¥ Always make sure item is marked
|
|
Char16 mark = GetMenuFontSize() < 12 ? gsPopup_SmallMark : checkMark;
|
|
::SetItemMark(inMenuH, inCurrentItem, mark);
|
|
}
|
|
|
|
}
|
|
|
|
//-----------------------------------
|
|
Int32 CSizePopup::GetFontSizeFromMenuItem(Int32 inMenuItem) const
|
|
//-----------------------------------
|
|
{
|
|
Str255 sizeString;
|
|
Int32 fontSize = 0;
|
|
|
|
::GetMenuItemText(const_cast<CSizePopup*>(this)->GetMacMenuH(), inMenuItem, sizeString);
|
|
|
|
myStringToNum(sizeString, &fontSize);
|
|
return fontSize;
|
|
}
|
|
|
|
//-----------------------------------
|
|
void CSizePopup::SetFontSize(Int32 inFontSize)
|
|
//-----------------------------------
|
|
{
|
|
mFontSize = inFontSize;
|
|
if (inFontSize)
|
|
{
|
|
MenuHandle sizeMenu = GetMacMenuH();
|
|
short menuSize = ::CountMItems(sizeMenu);
|
|
Boolean isOther = true;
|
|
for (int i = 1; i <= menuSize; ++i)
|
|
{
|
|
CStr255 sizeString;
|
|
::GetMenuItemText(sizeMenu, i, sizeString);
|
|
Int32 fontSize = 0;
|
|
myStringToNum(sizeString, &fontSize);
|
|
if (fontSize == inFontSize)
|
|
{
|
|
SetValue(i);
|
|
if (i != menuSize)
|
|
isOther = false;
|
|
break;
|
|
}
|
|
}
|
|
if (isOther)
|
|
SetValue(menuSize);
|
|
}
|
|
}
|
|
|
|
//-----------------------------------
|
|
void CSizePopup::SetValue(Int32 inValue)
|
|
//-----------------------------------
|
|
{
|
|
// ¥ We intentionally do not guard against setting the value to the
|
|
// same value the popup current has. This is so that the other
|
|
// size stuff works correctly.
|
|
|
|
// ¥ Get the current item setup in the menu
|
|
MenuHandle menuH = GetMacMenuH();
|
|
if ( menuH )
|
|
{
|
|
SetUpCurrentMenuItem( menuH, inValue );
|
|
}
|
|
|
|
if (inValue < mMinValue) { // Enforce min/max range
|
|
inValue = mMinValue;
|
|
} else if (inValue > mMaxValue) {
|
|
inValue = mMaxValue;
|
|
}
|
|
|
|
mValue = inValue; // Store new value
|
|
BroadcastValueMessage(); // Inform Listeners of value change
|
|
|
|
// ¥ Now we need to get the popup redrawn so that the change
|
|
// will be seen
|
|
Draw( nil );
|
|
|
|
} // LGAPopup::SetValue
|
|
|
|
//-----------------------------------
|
|
Boolean CSizePopup::TrackHotSpot(Int16 inHotSpot, Point inPoint, Int16 inModifiers)
|
|
//-----------------------------------
|
|
{
|
|
// Portions of this function are from LGAPopup.cp in PowerPlant
|
|
|
|
// ¥ We only want the popup menu to appear if the mouse went down
|
|
// in the our hot spot which is the popup portion of the control
|
|
// not the label area
|
|
if ( PointInHotSpot( inPoint, inHotSpot ))
|
|
{
|
|
// ¥ Get things started off on the right foot
|
|
Boolean currInside = true;
|
|
Boolean prevInside = false;
|
|
HotSpotAction( inHotSpot, currInside, prevInside );
|
|
|
|
// ¥ We skip the normal tracking that is done in the control as
|
|
// the call to PopupMenuSelect will take control of the tracking
|
|
// once the menu is up
|
|
// ¥ Now we need to handle the display of the actual popup menu
|
|
// we start by setting up some values that we will need
|
|
Int16 menuID = 0;
|
|
Int16 menuItem = GetValue();
|
|
Int16 currItem = IsPulldownMenu() ? 1 : GetValue();
|
|
Point popLoc;
|
|
GetPopupMenuPosition( popLoc );
|
|
|
|
// ¥ Call our utility function which handles the display of the menu
|
|
// menu is disposed of inside this function
|
|
HandlePopupMenuSelect( popLoc, currItem, menuID, menuItem );
|
|
|
|
if ( menuItem > 0)
|
|
{
|
|
if ( menuItem == ::CountMItems( GetMacMenuH() ))
|
|
{
|
|
StDialogHandler handler(Wind_OtherSizeDialog, nil);
|
|
LWindow* dialog = handler.GetDialog();
|
|
LEditField *sizeField = (LEditField *)dialog->FindPaneByID(1504);
|
|
Assert_(sizeField);
|
|
sizeField->SetValue(GetFontSize());
|
|
sizeField->SelectAll();
|
|
|
|
// Run the dialog
|
|
MessageT message = msg_Nothing;
|
|
do
|
|
{
|
|
message = handler.DoDialog();
|
|
} while (message == msg_Nothing);
|
|
|
|
if (msg_ChangeFontSize == message)
|
|
{
|
|
SetFontSize(sizeField->GetValue());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SetFontSize(GetFontSizeFromMenuItem(menuItem));
|
|
}
|
|
}
|
|
|
|
// ¥ Make sure that we get the HotSpotAction called one last time
|
|
HotSpotAction( inHotSpot, false, true );
|
|
|
|
return menuItem > 0;
|
|
}
|
|
else
|
|
return false;
|
|
|
|
}
|
|
|
|
//-----------------------------------
|
|
void CSizePopup::MarkRealFontSizes(LGAPopup *fontPopup)
|
|
//-----------------------------------
|
|
{
|
|
CStr255 fontName;
|
|
::GetMenuItemText( fontPopup->GetMacMenuH(),
|
|
fontPopup->GetValue(),
|
|
fontName);
|
|
GetFNum(fontName, &mFontNumber);
|
|
MarkRealFontSizes(mFontNumber);
|
|
}
|
|
|
|
//-----------------------------------
|
|
void CSizePopup::MarkRealFontSizes(short fontNum)
|
|
//-----------------------------------
|
|
{
|
|
Str255 itemString;
|
|
MenuHandle sizeMenu;
|
|
short menuSize;
|
|
|
|
sizeMenu = GetMacMenuH();
|
|
menuSize = CountMItems(sizeMenu);
|
|
|
|
for (short menuItem = 1; menuItem <= menuSize; ++menuItem)
|
|
{
|
|
Int32 fontSize;
|
|
::GetMenuItemText(sizeMenu, menuItem, itemString);
|
|
fontSize = 0;
|
|
myStringToNum(itemString, &fontSize);
|
|
|
|
Style theSyle;
|
|
|
|
if (fontSize && RealFont(fontNum, fontSize))
|
|
{
|
|
theSyle = outline;
|
|
}
|
|
else
|
|
{
|
|
theSyle = normal;
|
|
}
|
|
::SetItemStyle( sizeMenu,
|
|
menuItem,
|
|
theSyle);
|
|
}
|
|
}
|
|
|
|
//-----------------------------------
|
|
void CSizePopup::DrawPopupTitle()
|
|
// DrawPopupTitle is overridden to draw in the outline style
|
|
// as needed
|
|
//-----------------------------------
|
|
{
|
|
StColorPenState theColorPenState;
|
|
StTextState theTextState;
|
|
|
|
// ¥ Get some loal variables setup including the rect for the title
|
|
ResIDT textTID = GetTextTraitsID();
|
|
Rect titleRect;
|
|
Str255 title;
|
|
GetCurrentItemTitle( title );
|
|
|
|
// ¥ Figure out what the justification is from the text trait and
|
|
// get the port setup with the text traits
|
|
UTextTraits::SetPortTextTraits( textTID );
|
|
|
|
// ¥ Set outline style if it's an outline size
|
|
|
|
if (GetMacMenuH() && GetValue() != ::CountMItems(GetMacMenuH()))
|
|
{
|
|
Int32 fontSize;
|
|
CStr255 itemString;
|
|
|
|
::GetMenuItemText(GetMacMenuH(), GetValue(), itemString);
|
|
fontSize = 0;
|
|
myStringToNum(itemString, &fontSize);
|
|
|
|
Style theSyle;
|
|
|
|
if (fontSize && ::RealFont(mFontNumber, fontSize))
|
|
{
|
|
theSyle = outline;
|
|
}
|
|
else
|
|
{
|
|
theSyle = normal;
|
|
}
|
|
|
|
::TextFace(theSyle);
|
|
}
|
|
|
|
// ¥ Set up the title justification which is always left justified
|
|
Int16 titleJust = teFlushLeft;
|
|
|
|
// ¥ Get the current item's title
|
|
Str255 currentItemTitle;
|
|
GetCurrentItemTitle( currentItemTitle );
|
|
|
|
// ¥ Calculate the title rect
|
|
CalcTitleRect( titleRect );
|
|
|
|
// ¥ Kludge for drawing (correctly) in outline style left-justified
|
|
Rect actualRect;
|
|
UNewTextDrawing::MeasureWithJustification(
|
|
(char*) ¤tItemTitle[1],
|
|
currentItemTitle[0],
|
|
titleRect,
|
|
titleJust,
|
|
actualRect);
|
|
actualRect.right += 2;
|
|
titleRect = actualRect;
|
|
titleJust = teJustRight;
|
|
|
|
// ¥ Set up the text color which by default is black
|
|
RGBColor textColor;
|
|
::GetForeColor( &textColor );
|
|
|
|
// ¥ Loop over any devices we might be spanning and handle the drawing
|
|
// appropriately for each devices screen depth
|
|
StDeviceLoop theLoop( titleRect );
|
|
Int16 depth;
|
|
while ( theLoop.NextDepth( depth ))
|
|
{
|
|
if ( depth < 4 ) // ¥ BLACK & WHITE
|
|
{
|
|
// ¥ If the control is dimmed then we use the grayishTextOr
|
|
// transfer mode to draw the text
|
|
if ( !IsEnabled())
|
|
{
|
|
::RGBForeColor( &UGAColorRamp::GetBlackColor() );
|
|
::TextMode( grayishTextOr );
|
|
}
|
|
else if ( IsEnabled() && IsHilited() )
|
|
{
|
|
// ¥ When we are hilited we simply draw the title in white
|
|
::RGBForeColor( &UGAColorRamp::GetWhiteColor() );
|
|
}
|
|
|
|
// ¥ Now get the actual title drawn with all the appropriate settings
|
|
UTextDrawing::DrawWithJustification(
|
|
(char*) ¤tItemTitle[1],
|
|
currentItemTitle[0],
|
|
titleRect,
|
|
titleJust);
|
|
}
|
|
else // ¥ COLOR
|
|
{
|
|
// ¥ If control is selected we always draw the text in the title
|
|
// hilite color, if requested
|
|
if ( IsHilited())
|
|
::RGBForeColor( &UGAColorRamp::GetWhiteColor() );
|
|
|
|
// ¥ If the box is dimmed then we have to do our own version of the
|
|
// grayishTextOr as it does not appear to work correctly across
|
|
// multiple devices
|
|
if ( !IsEnabled() || !IsActive())
|
|
{
|
|
textColor = UGraphicsUtilities::Lighten( &textColor );
|
|
::TextMode( srcOr );
|
|
::RGBForeColor( &textColor );
|
|
}
|
|
|
|
// ¥ Now get the actual title drawn with all the appropriate settings
|
|
UTextDrawing::DrawWithJustification(
|
|
(char*) ¤tItemTitle[1],
|
|
currentItemTitle[0],
|
|
titleRect,
|
|
titleJust);
|
|
}
|
|
}
|
|
} // CSizePopup::DrawPopupTitle
|
|
|
|
//-----------------------------------
|
|
void CSizePopup::DrawPopupArrow()
|
|
//-----------------------------------
|
|
{
|
|
StColorPenState theColorPenState;
|
|
|
|
// ¥ Get the local popup frame rect
|
|
Rect popupFrame;
|
|
CalcLocalPopupFrameRect( popupFrame );
|
|
|
|
// ¥ Set up some variables used in the drawing loop
|
|
Int16 start = (( UGraphicsUtilities::RectHeight( popupFrame ) - gsPopup_ArrowHeight) / 2) + 1;
|
|
|
|
// ¥ Figure out the left and right edges based on whether we are drawing
|
|
// only the arrow portion or the entire popup
|
|
Int16 leftEdge = gsPopup_ArrowButtonWidth - 6;
|
|
Int16 rightEdge = leftEdge - (gsPopup_ArrowWidth - 1);
|
|
|
|
popupFrame.top = popupFrame.top + start;
|
|
popupFrame.bottom = popupFrame.top + gsPopup_ArrowHeight - 1;
|
|
popupFrame.left = popupFrame.right - leftEdge;
|
|
popupFrame.right = popupFrame.right - rightEdge;
|
|
|
|
UGraphicGizmos::DrawPopupArrow(
|
|
popupFrame,
|
|
IsEnabled(),
|
|
IsActive(),
|
|
IsHilited());
|
|
} // CSizePopup::DrawPopupArrow
|
|
|