netscape-revival
sun-java/awt.bad/macos/MChoicePeer.cp
//##############################################################################
//##############################################################################
//
// File: MChoicePeer.cp
// Author: Dan Clifford
//
// Copyright © 1995-1996, Netscape Communications Corporation
//
//##############################################################################
//##############################################################################
#include "MToolkit.h"
#include <Types.h>
#include <Memory.h>
#include <LButton.h>
#include <LStdControl.h>
#include <LView.h>
extern "C" {
#include <stdlib.h>
#include "native.h"
#include "typedefs_md.h"
#include "java_awt_Color.h"
#include "java_awt_Font.h"
#include "java_awt_Component.h"
#include "java_awt_Choice.h"
#include "sun_awt_macos_MComponentPeer.h"
#include "sun_awt_macos_MChoicePeer.h"
};
#include "MChoicePeer.h"
#include "MCanvasPeer.h"
#include "MComponentPeer.h"
#include "LMacGraphics.h"
#include <UTextTraits.h>
#ifdef UNICODE_FONTLIST
enum {
kScriptCodeInMenu = 28 // $1C in keyboard equivalent field mean the text is in the script
// code specified in the icon field.
};
#endif
enum {
kTemplatePopupMenuResID = -3496
};
//##############################################################################
//##############################################################################
#pragma mark MComponentPeer IMPLEMENTATION
#pragma mark -
Handle gActualPopupMenu = NULL;
Boolean gChoiceInitializing = false;
MChoicePeer *gCurrentChoicePeer = NULL;
MChoicePeer::
MChoicePeer(struct SPaneInfo &newScrollbarInfo):LPane(newScrollbarInfo)
{
}
MChoicePeer::
~MChoicePeer()
{
DisposeJavaDataForPane(this);
}
Int32
MChoicePeer::GetValue() const
{
Classsun_awt_macos_MComponentPeer *componentPeer = (Classsun_awt_macos_MComponentPeer *)unhand(PaneToPeer(this));
Hjava_awt_Choice *choiceHandle;
choiceHandle = (Hjava_awt_Choice *)componentPeer->target;
return unhand(choiceHandle)->selectedIndex;
}
Boolean
MChoicePeer::FocusDraw()
{
Boolean shouldRefocus = ShouldRefocusAWTPane(this);
Boolean result = false;
gInPaneFocusDraw = true;
result = inherited::FocusDraw();
gInPaneFocusDraw = false;
if (shouldRefocus && result)
PreparePeerGrafPort(PaneToPeer(this), NULL);
return result;
}
void
MChoicePeer::CalculateMenuDimensions(short &width)
{
MenuHandle choiceMenu;
choiceMenu = (MenuHandle)unhand((Hsun_awt_macos_MChoicePeer *)(PaneToPeer(this)))->mActualMenuContents;
if ((**choiceMenu).menuWidth == -1) {
// Switch to the Window Manager port, and set the font and
// size to be appropriate for the popup. Save everything
// away so that we can restore ports Õn stuff properly.
CGrafPtr windowManagerPort;
GrafPtr savedPort;
short savedFont,
savedSize,
savedSysFont;
GetPort(&savedPort);
GetCWMgrPort(&windowManagerPort);
SetPort((GrafPtr)windowManagerPort);
savedFont = windowManagerPort->txFont;
savedSize = windowManagerPort->txSize;
UTextTraits::SetPortTextTraits(kDefaultAWTTextTraitsID);
savedSysFont = LMGetSysFontFam();
LMSetSysFontFam(9);
CalcMenuSize(choiceMenu);
// Restore ports and Quickdraw info
LMSetSysFontFam(savedSysFont);
::TextFont(savedFont);
::TextSize(savedSize);
SetPort(savedPort);
}
width = (**choiceMenu).menuWidth;
}
void
MChoicePeer::DrawSelf()
{
Rect frameRect,
popupRectangle,
tempRect;
MenuHandle choiceMenu;
Str255 menuItemText;
Boolean enabled = IsEnabled();
short width;
CalcLocalFrameRect(frameRect);
UTextTraits::SetPortTextTraits(kDefaultAWTTextTraitsID);
choiceMenu = (MenuHandle)unhand((Hsun_awt_macos_MChoicePeer *)(PaneToPeer(this)))->mActualMenuContents;
CalculateMenuDimensions(width);
// The choice peerÕs rectangle is a sub-rectangle
// of the frame rectangle. It is kChoicePeerDefaultHeight
// pixels high, and menuWidth pixels wide.
popupRectangle = frameRect;
if (width > (popupRectangle.right - popupRectangle.left - kChoicePeerDefaultExtraWidth))
width = popupRectangle.right - popupRectangle.left - kChoicePeerDefaultExtraWidth;
if (width < 0)
width = 0;
popupRectangle.bottom = popupRectangle.top + kChoicePeerDefaultHeight;
popupRectangle.right = popupRectangle.left + width + kChoicePeerDefaultExtraWidth;
// Draw the choice peerÕs frame and its drop shadow. If the peer is
// disabled, then draw in grey.
if (enabled)
::ForeColor(blackColor);
else {
// FIX ME
// RGBColor disabledGrey = { 140 << 8, 140 << 8, 140 << 8 };
// ::RGBForeColor();
}
::BackColor(whiteColor);
FrameRect(&popupRectangle);
tempRect = popupRectangle;
InsetRect(&tempRect, 1, 1);
EraseRect(&tempRect);
MoveTo(popupRectangle.left + 3, popupRectangle.bottom);
LineTo(popupRectangle.right, popupRectangle.bottom);
LineTo(popupRectangle.right, popupRectangle.top + 3);
// Draw the text of the current item.
::MoveTo(popupRectangle.left + kChoicePeerItemTextIndent, popupRectangle.bottom - kChoicePeerItemTextIndentUp);
GetMenuItemText(choiceMenu, GetValue() + 1, menuItemText);
#ifdef UNICODE_FONTLIST
// Ok, the text is in other script. We have to swtich the font before we draw it.
short cmd;
::GetItemCmd(choiceMenu, GetValue() + 1, &cmd);
if(cmd == kScriptCodeInMenu)
{
short script;
::GetItemIcon(choiceMenu, GetValue() + 1, &script);
::TextFont(::GetScriptVariable(script, smScriptSysFondSize) >> 16);
}
#endif
DrawString(menuItemText);
// Draw the arrow.
for (UInt32 currentLine = 0; currentLine < 5; currentLine++) {
::MoveTo(popupRectangle.right - kChoicePeerArrowRightIndent + currentLine,
popupRectangle.top + kChoicePeerArrowDownIndent + currentLine);
::Line(8 - (currentLine * 2), 0);
}
}
void
MChoicePeer::ClickSelf(const SMouseDownEvent &inMouseDown)
{
MenuHandle choiceMenu;
Rect frameRect,
popupRectangle;
Point selectPoint;
long newValue,
previousValue = GetValue();
short width;
CalculateMenuDimensions(width);
// In order to pervent flicker, erase the current contents of
// the popup, and redraw when we are done.
CalcLocalFrameRect(frameRect);
popupRectangle = frameRect;
popupRectangle.bottom = popupRectangle.top + kChoicePeerDefaultHeight;
popupRectangle.right = popupRectangle.left + width + kChoicePeerDefaultExtraWidth;
FocusDraw();
choiceMenu = (MenuHandle)unhand((Hsun_awt_macos_MChoicePeer *)(PaneToPeer(this)))->mActualMenuContents;
selectPoint.h = frameRect.left;
selectPoint.v = frameRect.top;
LocalToPortPoint(selectPoint);
PortToGlobalPoint(selectPoint);
// Temporarily insert this menu into the hierarchical portion
// of the menu bar and call PopupMenuSelect to let the
// user make the choice.
InsertMenu(choiceMenu, -1);
// Save off our port and port information
{
CGrafPtr wMgrCPort;
GetCWMgrPort(&wMgrCPort);
StPortOriginState savedPortInfo((GrafPtr)wMgrCPort);
StTextState savedFontInfo;
SInt16 savedFont;
UTextTraits::SetPortTextTraits(kDefaultAWTTextTraitsID);
savedFont = LMGetSysFontFam();
LMSetSysFontFam(9);
// Mark the currently selected item in the choice peer
// with the '¥' character.
SetItemMark(choiceMenu, previousValue + 1, '¥');
newValue = PopUpMenuSelect(choiceMenu, selectPoint.v + 1, selectPoint.h + 1, previousValue + 1);
LMSetSysFontFam(savedFont);
}
// Remove the checkmark set above.
SetItemMark(choiceMenu, previousValue + 1, 0x00);
// Remove the menu from the hierarchical portion of the menu
// bar until the next time we need it.
DeleteMenu((**choiceMenu).menuID);
LView::OutOfFocus(NULL);
// If the selection from the popup was non zero, then call the
// peerÕs action procedure (remember, selection in Choice.class
// are zero based, Mac Menu Manager selections are 1 based),
// and redraw the popup with the newly selected value.
if (newValue != 0) {
newValue = (newValue & 0xFFFF) - 1;
MToolkitExecutJavaDynamicMethod(PaneToPeer(this), "handleAction", "(I)V", newValue);
}
}
//##############################################################################
//##############################################################################
void sun_awt_macos_MChoicePeer_create(struct Hsun_awt_macos_MChoicePeer *choicePeerHandle, struct Hsun_awt_macos_MComponentPeer *hostPeerHandle)
{
Classsun_awt_macos_MChoicePeer *choicePeer = (Classsun_awt_macos_MChoicePeer*)unhand(choicePeerHandle);
Classjava_awt_Choice *choiceTarget = (Classjava_awt_Choice*)unhand(choicePeer->target);
LView *superView = (LView *)PeerToPane(hostPeerHandle);
struct SPaneInfo newChoiceInfo;
memset(&newChoiceInfo, 0, sizeof(newChoiceInfo));
newChoiceInfo.paneID = MChoicePeer::class_ID;
newChoiceInfo.visible = triState_Off;
newChoiceInfo.left = choiceTarget->x;
newChoiceInfo.top = choiceTarget->y;
newChoiceInfo.width = choiceTarget->width;
newChoiceInfo.height = choiceTarget->height;
newChoiceInfo.left = choiceTarget->x;
newChoiceInfo.top = choiceTarget->y;
newChoiceInfo.width = 90;
newChoiceInfo.enabled = triState_Off;
newChoiceInfo.userCon = (UInt32)choicePeerHandle;
newChoiceInfo.superView = superView;
gChoiceInitializing = true;
MChoicePeer *choicePane = NULL;
try {
choicePane = new MChoicePeer(newChoiceInfo);
}
catch (...) {
SignalError(0, JAVAPKG "OutOfMemoryError", 0);
return;
}
choicePane->Enable();
choicePane->Show();
gChoiceInitializing = false;
// Each choice peer needs to maintian its own private copy
// of a MenuHandle to keep its items close at hand. We
// create this MenuHandle from a tempalte MENU resource
// with ID kTemplatePopupMenuResID. We detach it so that
// other clients get their own, unique copy.
MenuHandle privateCopy = GetMenu(kTemplatePopupMenuResID);
DetachResource((Handle)privateCopy);
choicePeer->mActualMenuContents = (long)privateCopy;
choicePeer->mIsChoice = true;
choicePeer->mOwnerPane = (long)choicePane;
choicePeer->mRecalculateClip = true;
ClearCachedAWTRefocusPane();
}
void sun_awt_macos_MChoicePeer_addItem(struct Hsun_awt_macos_MChoicePeer *componentPeerHandle, struct Hjava_lang_String *textHandle, long itemNumber)
{
Classsun_awt_macos_MChoicePeer *componentPeer = unhand(componentPeerHandle);
MChoicePeer *componentPane = (MChoicePeer *)PeerToPane((Hsun_awt_macos_MComponentPeer *)componentPeerHandle);
Str255 itemText;
if (componentPane == NULL)
return;
// i18n fix!!!
#ifdef UNICODE_FONTLIST
short encoding = intl_javaString2CEncodingString(textHandle,
(unsigned char *)(itemText + 1), 255);
#else
javaString2CString(textHandle, (char *)(itemText + 1), 255);
#endif
itemText[0] = strlen((char *)(itemText + 1));
// Convert the java string into a C string. Maximum length is 255 - 5
// because of Menu Manager bug which overflows over 255.
if (itemText[0] > 250)
itemText[0] = 250;
MenuHandle choiceMenu = (MenuHandle)(componentPeer->mActualMenuContents);
// Substitute a longer dash for a normal dash if it is the the first item
// in the list. This makes sure that the item is more that just a separator.
if (itemText[1] == '-')
itemText[1] = 'Ñ';
InsertMenuItem(choiceMenu, "\px", itemNumber);
SetMenuItemText(choiceMenu, itemNumber + 1,itemText);
#ifdef UNICODE_FONTLIST
if(! UEncoding::IsMacRoman(encoding))
{
SetItemCmd(choiceMenu, itemNumber + 1, kScriptCodeInMenu);
SetItemIcon(choiceMenu, itemNumber + 1, UEncoding::GetScriptID(encoding));
}
#endif
}
void sun_awt_macos_MChoicePeer_remove(struct Hsun_awt_macos_MChoicePeer *componentPeerHandle, long whichItem)
{
Classsun_awt_macos_MChoicePeer *componentPeer = unhand(componentPeerHandle);
MChoicePeer *componentPane = (MChoicePeer *)PeerToPane((Hsun_awt_macos_MComponentPeer *)componentPeerHandle);
MenuHandle choiceMenu = (MenuHandle)(componentPeer->mActualMenuContents);
if (componentPane == NULL)
return;
DeleteMenuItem(choiceMenu, whichItem);
}
void sun_awt_macos_MChoicePeer_select(struct Hsun_awt_macos_MChoicePeer *componentPeerHandle, long whichItem)
{
Classsun_awt_macos_MComponentPeer *componentPeer = unhand((Hsun_awt_macos_MComponentPeer *)componentPeerHandle);
MChoicePeer *componentPane = (MChoicePeer *)PeerToPane((Hsun_awt_macos_MComponentPeer *)componentPeerHandle);
Hjava_awt_Choice *choiceHandle;
Rect tempRect;
if (componentPane == NULL)
return;
choiceHandle = (Hjava_awt_Choice *)componentPeer->target;
unhand(choiceHandle)->selectedIndex = whichItem;
// Invalidate the text area, minus the scrollbars
// so that the text is re-drawn.
// dkc 2/7/96
LView::OutOfFocus(NULL);
componentPane->FocusDraw();
componentPane->CalcLocalFrameRect(tempRect);
::InvalRect(&tempRect);
}