Files
Mozilla/mozilla/widget/src/mac/nsTextAreaWidget.cpp
pierre%netscape.com 4db27e1c5c Replaced with the previous contents of nsTextWidget.
nsTextWidget is 1-line field and can be done with TextEdit or the Appearance Manager instead of WASTE, while nsTextArea should use WASTE.


git-svn-id: svn://10.0.0.236/trunk@14069 18797224-902f-48f8-a5cc-f745e15eee43
1998-11-04 07:32:33 +00:00

578 lines
16 KiB
C++

/* -*- Mode: C++; tab-width: 2; 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.
*/
#include "nsTextAreaWidget.h"
#include "nsMacWindow.h"
#include "nsToolkit.h"
#include "nsColor.h"
#include "nsGUIEvent.h"
#include "nsString.h"
#define DBG 0
NS_IMPL_ADDREF(nsTextAreaWidget);
NS_IMPL_RELEASE(nsTextAreaWidget);
/**-------------------------------------------------------------------------------
* nsTextAreaWidget Constructor
* @update dc 09/10/98
*/
nsTextAreaWidget::nsTextAreaWidget(): nsWindow()
{
NS_INIT_REFCNT();
mIsPasswordCallBacksInstalled = PR_FALSE;
mMakeReadOnly=PR_FALSE;
mMakePassword=PR_FALSE;
mTE_Data = nsnull;
strcpy(gInstanceClassName, "nsTextAreaWidget");
//mBackground = NS_RGB(124, 124, 124);
}
/**-------------------------------------------------------------------------------
* The create method for a nsTextAreaWidget, using a nsIWidget as the parent
* @update dc 09/10/98
* @param aParent -- the widget which will be this widgets parent in the tree
* @param aRect -- The bounds in parental coordinates of this widget
* @param aHandleEventFunction -- Procedures to be executed for this widget
* @param aContext -- device context to be used by this widget
* @param aAppShell --
* @param aToolkit -- toolkit to be used by this widget
* @param aInitData -- Initialization data used by frames
* @return -- NS_OK if everything was created correctly
*/
NS_IMETHODIMP nsTextAreaWidget::Create(nsIWidget *aParent,const nsRect &aRect,EVENT_CALLBACK aHandleEventFunction,
nsIDeviceContext *aContext,nsIAppShell *aAppShell,nsIToolkit *aToolkit, nsWidgetInitData *aInitData)
{
LongRect destRect,viewRect;
PRUint32 teFlags=0;
GrafPtr curport;
PRInt32 offx,offy;
nsWindow::Create(aParent, aRect, aHandleEventFunction,
aContext, aAppShell, aToolkit, aInitData);
mWindowPtr = nsnull;
if (aParent)
mWindowPtr = (WindowPtr)aParent->GetNativeData(NS_NATIVE_DISPLAY);
else if (aAppShell)
mWindowPtr = (WindowPtr)aAppShell->GetNativeData(NS_NATIVE_SHELL);
// Initialize the TE record
CalcOffset(offx,offy);
viewRect.left = aRect.x;
viewRect.top = aRect.y;
viewRect.right = aRect.x+aRect.width;
viewRect.bottom = aRect.y+aRect.height;
destRect = viewRect;
::GetPort(&curport);
::SetPort(mWindowPtr);
//::SetOrigin(-offx,-offy);
WENew(&destRect,&viewRect,teFlags,&mTE_Data);
//::SetOrigin(0,0);
::SetPort(curport);
return NS_OK;
}
/**-------------------------------------------------------------------------------
* Destuctor for the nsTextAreaWidget
* @update dc 08/31/98
*/
nsTextAreaWidget::~nsTextAreaWidget()
{
if(mTE_Data!=nsnull)
WEDispose(mTE_Data);
}
/**-------------------------------------------------------------------------------
* Implement the standard QueryInterface for NS_IWIDGET_IID and NS_ISUPPORTS_IID
* @update dc 08/31/98
* @param aIID The name of the class implementing the method
* @param _classiiddef The name of the #define symbol that defines the IID
* for the class (e.g. NS_ISUPPORTS_IID)
*/
nsresult nsTextAreaWidget::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
static NS_DEFINE_IID(kITextAreaWidgetIID, NS_ITEXTAREAWIDGET_IID);
if (aIID.Equals(kITextAreaWidgetIID)) {
AddRef();
*aInstancePtr = (void**)(nsITextAreaWidget*)this;
return NS_OK;
}
return nsWindow::QueryInterface(aIID, aInstancePtr);
}
//-------------------------------------------------------------------------
/**
* The onPaint handler for a nsTextAreaWidget -- this may change, inherited from windows
* @param aEvent -- The paint event to respond to
* @return -- PR_TRUE if painted, false otherwise
*/
PRBool nsTextAreaWidget::OnPaint(nsPaintEvent & aEvent)
{
PRInt32 offx,offy;
nsRect therect;
Rect macrect;
GrafPtr theport;
RgnHandle thergn;
CalcOffset(offx,offy);
::GetPort(&theport);
::SetPort(mWindowPtr);
::SetOrigin(-offx,-offy);
GetBounds(therect);
nsRectToMacRect(therect,macrect);
thergn = ::NewRgn();
::GetClip(thergn);
::ClipRect(&macrect);
::EraseRect(&macrect);
::PenSize(1,1);
WEActivate(mTE_Data);
WEUpdate(nsnull,mTE_Data);
::FrameRect(&macrect);
::SetClip(thergn);
::SetOrigin(0,0);
::SetPort(theport);
return PR_FALSE;
}
//-------------------------------------------------------------------------
/**
* The Keydown handler for a nsTextAreaWidget
* @param aKey -- the key pressed
* @param aModifiers -- the modifiers of the key pressed, like command, shift, etc.
* @return -- PR_TRUE if painted, false otherwise
*/
void nsTextAreaWidget::PrimitiveKeyDown(PRInt16 aKey,PRInt16 aModifiers)
{
PRBool result=PR_TRUE;
GrafPtr thePort;
RgnHandle theRgn;
nsRect theRect;
Rect macRect;
PRInt32 offX,offY;
CalcOffset(offX,offY);
::GetPort(&thePort);
::SetPort(mWindowPtr);
GetBounds(theRect);
nsRectToMacRect(theRect,macRect);
theRgn = ::NewRgn();
::GetClip(theRgn);
::ClipRect(&macRect);
WEKey(aKey,aModifiers,mTE_Data);
::SetClip(theRgn);
::DisposeRgn(theRgn);
::SetPort(thePort);
}
/**-------------------------------------------------------------------------------
* DispatchMouseEvent handle an event for this nsTextAreaWidget
* @update dc 10/10/98
* @Param aEvent -- The mouse event to respond to for this button
* @return -- True if the event was handled, PR_FALSE if we did not handle it.
*/
PRBool nsTextAreaWidget::DispatchMouseEvent(nsMouseEvent &aEvent)
{
PRBool result=PR_TRUE;
Point mouseLoc;
PRInt16 modifiers=0;
nsRect therect;
Rect macrect;
PRInt32 offx,offy;
GrafPtr theport;
switch (aEvent.message){
case NS_MOUSE_LEFT_BUTTON_DOWN:
CalcOffset(offx,offy);
::GetPort(&theport);
::SetPort(mWindowPtr);
GetBounds(therect);
nsRectToMacRect(therect,macrect);
::ClipRect(&macrect);
mouseLoc.h = aEvent.point.x;
mouseLoc.v = aEvent.point.y;
WEClick(mouseLoc,modifiers,aEvent.time,mTE_Data);
::SetPort(theport);
result = PR_FALSE;
break;
case NS_MOUSE_LEFT_BUTTON_UP:
break;
case NS_MOUSE_EXIT:
break;
case NS_MOUSE_ENTER:
break;
}
return result;
}
//-------------------------------------------------------------------------
PRBool nsTextAreaWidget::DispatchWindowEvent(nsGUIEvent &event)
{
PRBool keyHandled = nsWindow::DispatchWindowEvent(event);
if (! keyHandled)
{
if (event.eventStructType == NS_KEY_EVENT)
{
if (event.message == NS_KEY_DOWN)
{
char theChar;
short theModifiers;
EventRecord* theOSEvent = (EventRecord*)event.nativeMsg;
if (theOSEvent)
{
theChar = (theOSEvent->message & charCodeMask);
theModifiers = theOSEvent->modifiers;
}
else
{
nsKeyEvent* keyEvent = (nsKeyEvent*)&event;
theChar = keyEvent->keyCode;
if (keyEvent->isShift)
theModifiers = shiftKey;
if (keyEvent->isControl)
theModifiers |= controlKey;
if (keyEvent->isAlt)
theModifiers |= optionKey;
}
if (theChar != NS_VK_RETURN) // don't pass Return: nsTextAreaWidget is a single line editor
{
PrimitiveKeyDown(theChar, theModifiers);
keyHandled = PR_TRUE;
}
}
}
}
return (keyHandled);
}
/**-------------------------------------------------------------------------------
* Sets the password flag. If true, asteriks are the onlything displayed
* @update dc 10/10/98
* @Param aIsPassword -- if true, password attribute is used.
* @return -- if everything is ok
*/
NS_METHOD nsTextAreaWidget::SetPassword(PRBool aIsPassword)
{
if ( aIsPassword) {
mMakePassword = PR_TRUE;
return NS_OK;
}
return NS_OK;
}
/**-------------------------------------------------------------------------------
* Sets the readonly flag. If true, you can only read the text
* @update dc 10/10/98
* @Param aReadOnlyFlag -- if true, readoly attribute is used.
* @Param aOldFlag -- the old setting
* @return -- if everything is ok
*/
NS_METHOD nsTextAreaWidget::SetReadOnly(PRBool aReadOnlyFlag, PRBool& aOldFlag)
{
aOldFlag = mMakeReadOnly;
mMakeReadOnly = aReadOnlyFlag;
return NS_OK;
}
/**-------------------------------------------------------------------------------
* Sets the maximum number of characters allowed.
* @update dc 10/10/98
* @Param aChars -- number of characters allowed
* @return -- if everything is ok
*/
NS_METHOD nsTextAreaWidget::SetMaxTextLength(PRUint32 aChars)
{
return NS_OK;
}
/**-------------------------------------------------------------------------------
* Gets the text from this widget
* @update dc 10/10/98
* @Param aTextBuffer -- string to fill in
* @Param aBufferSize -- size of the buffer passed in
* @Param aSize -- size of the string passed out
* @return -- if everything is ok
*/
NS_METHOD nsTextAreaWidget::GetText(nsString& aTextBuffer, PRUint32 aBufferSize, PRUint32& aSize)
{
Handle thetext;
PRInt32 len,i;
char *str;
thetext = WEGetText(mTE_Data);
len = WEGetTextLength(mTE_Data);
//HLock(thetext);
str = new char[len+1];
for(i=0;i<len;i++)
str[i] = (*thetext)[i];
str[len] = 0;
//HUnlock(thetext);
aTextBuffer.SetLength(0);
aTextBuffer.Append(str);
aSize = aTextBuffer.Length();
delete [] str;
return NS_OK;
}
/**-------------------------------------------------------------------------------
* Resize this widget
* @update dc 10/01/98
* @param aWidth -- x offset in widget local coordinates
* @param aHeight -- y offset in widget local coordinates
* @param aRepaint -- indicates if a repaint is needed.
* @return PR_TRUE if the pt is contained in the widget
*/
NS_IMETHODIMP nsTextAreaWidget::Resize(PRUint32 aWidth, PRUint32 aHeight, PRBool aRepaint)
{
nsSizeEvent event;
nsEventStatus eventStatus;
LongRect macRect;
mBounds.width = aWidth;
mBounds.height = aHeight;
if(nsnull!=mWindowRegion)
::DisposeRgn(mWindowRegion);
mWindowRegion = NewRgn();
SetRectRgn(mWindowRegion,mBounds.x,mBounds.y,mBounds.x+mBounds.width,mBounds.y+mBounds.height);
if(mTE_Data != nsnull){
macRect.top = mBounds.y;
macRect.left = mBounds.x;
macRect.bottom = mBounds.y+mBounds.height;
macRect.right = mBounds.x+mBounds.width;
WESetDestRect(&macRect,mTE_Data);
WESetViewRect(&macRect,mTE_Data);
}
if (aRepaint){
//¥TODO
}
event.message = NS_SIZE;
event.point.x = 0;
event.point.y = 0;
event.windowSize = &mBounds;
event.eventStructType = NS_SIZE_EVENT;
event.widget = this;
//this->DispatchEvent(&event, eventStatus);
return NS_OK;
}
/**-------------------------------------------------------------------------------
* Resize this widget
* @update dc 10/01/98
* @param aX -- left part of rectangle
* @param aY -- top of rectangle
* @param aWidth -- x offset in widget local coordinates
* @param aHeight -- y offset in widget local coordinates
* @param aW
* @return PR_TRUE
*/
NS_IMETHODIMP nsTextAreaWidget::Resize(PRUint32 aX, PRUint32 aY, PRUint32 aWidth, PRUint32 aHeight, PRBool aRepaint)
{
nsSizeEvent event;
nsEventStatus eventStatus;
LongRect macRect;
mBounds.x = aX;
mBounds.y = aY;
mBounds.width = aWidth;
mBounds.height = aHeight;
if(nsnull!=mWindowRegion)
::DisposeRgn(mWindowRegion);
mWindowRegion = NewRgn();
SetRectRgn(mWindowRegion,mBounds.x,mBounds.y,mBounds.x+mBounds.width,mBounds.y+mBounds.height);
if(mTE_Data != nsnull){
macRect.top = mBounds.y;
macRect.left = mBounds.x;
macRect.bottom = mBounds.y+mBounds.height;
macRect.right = mBounds.x+mBounds.width;
WESetDestRect(&macRect,mTE_Data);
WESetViewRect(&macRect,mTE_Data);
}
if (aRepaint){
//¥TODO
}
event.message = NS_SIZE;
event.point.x = 0;
event.point.y = 0;
event.windowSize = &mBounds;
event.widget = this;
event.eventStructType = NS_SIZE_EVENT;
//this->DispatchEvent(&event, eventStatus);
return NS_OK;
}
/**-------------------------------------------------------------------------------
* Set the text for this widget
* @update dc 10/01/98
* @param aText -- Text to use in this widget
* @param aSize -- size of the text to use here
* @return PR_TRUE
*/
PRUint32 nsTextAreaWidget::SetText(const nsString& aText, PRUint32& aSize)
{
char buffer[256];
PRInt32 len;
PRInt32 offx,offy;
GrafPtr theport;
CalcOffset(offx,offy);
::GetPort(&theport);
::SetPort(mWindowPtr);
//::SetOrigin(-offx,-offy);
this->RemoveText();
aText.ToCString(buffer,255);
len = strlen(buffer);
WEInsert(buffer,len,0,0,mTE_Data);
aSize = len;
//::SetOrigin(0,0);
::SetPort(theport);
return NS_OK;
}
/**-------------------------------------------------------------------------------
* insert text into this widget
* @update dc 10/01/98
* @param aText -- Text to use in this widget
* @param aStartPos - Starting position
* @param aEndtPos - Ending position
* @param aSize -- size of the text to use here
* @return PR_TRUE
*/
PRUint32 nsTextAreaWidget::InsertText(const nsString &aText, PRUint32 aStartPos, PRUint32 aEndPos, PRUint32& aSize)
{
char buffer[256];
PRInt32 len;
PRInt32 offX,offY;
GrafPtr thePort;
CalcOffset(offX,offY);
::GetPort(&thePort);
::SetPort(mWindowPtr);
//::SetOrigin(-offx,-offy);
aText.ToCString(buffer,255);
len = strlen(buffer);
WEInsert(buffer,len,0,0,mTE_Data);
aSize = len;
//::SetOrigin(0,0);
::SetPort(thePort);
return NS_OK;
}
/**-------------------------------------------------------------------------------
* Remove all the text for this widget
* @update dc 10/01/98
* @return PR_TRUE
*/
NS_METHOD nsTextAreaWidget::RemoveText()
{
WESetSelection(0, 32000,mTE_Data);
WEDelete(mTE_Data);
return NS_OK;
}
/**-------------------------------------------------------------------------------
* Select all the text for this widget
* @update dc 10/01/98
* @return PR_TRUE
*/
NS_METHOD nsTextAreaWidget::SelectAll()
{
WESetSelection(0, 32000,mTE_Data);
return NS_OK;
}
/**-------------------------------------------------------------------------------
* Set the text for this widget
* @update dc 10/01/98
* @param aStartSel -- start index of the text
* @param aEndSel -- end index of the text
* @return PR_TRUE
*/
NS_METHOD nsTextAreaWidget::SetSelection(PRUint32 aStartSel, PRUint32 aEndSel)
{
WESetSelection(aStartSel, aEndSel,mTE_Data);
return NS_OK;
}
/**-------------------------------------------------------------------------------
* Get the text for this widget
* @update dc 10/01/98
* @param aStartSel -- start index of the text
* @param aEndSel -- end index of the text
* @return PR_TRUE
*/
NS_METHOD nsTextAreaWidget::GetSelection(PRUint32 *aStartSel, PRUint32 *aEndSel)
{
WEGetSelection((long*)aStartSel,(long*)aEndSel,mTE_Data);
return NS_OK;
}
/**-------------------------------------------------------------------------------
* Set the caret position for this widget
* @update dc 10/01/98
* @param aPosition -- postition of text
* @return PR_TRUE
*/
NS_METHOD nsTextAreaWidget::SetCaretPosition(PRUint32 aPosition)
{
//mHelper->SetCaretPosition(aPosition);
return NS_OK;
}
/**-------------------------------------------------------------------------------
* Get the caret position for this widget
* @update dc 10/01/98
* @param aPosition -- postition of text
* @return PR_TRUE if the pt is contained in the widget
*/
NS_METHOD nsTextAreaWidget::GetCaretPosition(PRUint32& aPos)
{
//return mHelper->GetCaretPosition();
return NS_OK;
}