388 lines
11 KiB
C++
388 lines
11 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 "nsXPButton.h"
|
|
#include "nsxpfcCIID.h"
|
|
#include "nspr.h"
|
|
#include "nsIButton.h"
|
|
#include "nsWidgetsCID.h"
|
|
#include "nsXPFCToolkit.h"
|
|
#include "nsxpfcstrings.h"
|
|
|
|
#include "nsIAppShell.h"
|
|
#include "nsIWidget.h"
|
|
#include "nsITextWidget.h"
|
|
#include "nsIButton.h"
|
|
#include "nsIImageGroup.h"
|
|
#include "nsITimer.h"
|
|
#include "nsIThrobber.h"
|
|
#include "nsXPItem.h"
|
|
#include "nsIWebViewerContainer.h"
|
|
#include "nsViewsCID.h"
|
|
|
|
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
|
static NS_DEFINE_IID(kCXPButtonCID, NS_XP_BUTTON_CID);
|
|
static NS_DEFINE_IID(kCIXPButtonIID, NS_IXP_BUTTON_IID);
|
|
static NS_DEFINE_IID(kCButtonCID, NS_BUTTON_CID);
|
|
static NS_DEFINE_IID(kInsButtonIID, NS_IBUTTON_IID);
|
|
static NS_DEFINE_IID(kViewCID, NS_VIEW_CID);
|
|
|
|
#define DEFAULT_WIDTH 50
|
|
#define DEFAULT_HEIGHT 50
|
|
|
|
nsXPButton :: nsXPButton(nsISupports* outer) : nsXPItem(outer)
|
|
{
|
|
NS_INIT_REFCNT();
|
|
|
|
mMiniHoverImageRequest = nsnull;
|
|
mFullHoverImageRequest = nsnull;
|
|
mMiniPressedImageRequest = nsnull;
|
|
mFullPressedImageRequest = nsnull;
|
|
|
|
mState = eButtonState_none;
|
|
}
|
|
|
|
nsXPButton :: ~nsXPButton()
|
|
{
|
|
NS_IF_RELEASE(mMiniHoverImageRequest);
|
|
NS_IF_RELEASE(mFullHoverImageRequest);
|
|
NS_IF_RELEASE(mMiniPressedImageRequest);
|
|
NS_IF_RELEASE(mFullPressedImageRequest);
|
|
}
|
|
|
|
nsresult nsXPButton::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|
{
|
|
if (NULL == aInstancePtr) {
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
|
static NS_DEFINE_IID(kClassIID, kCXPButtonCID);
|
|
if (aIID.Equals(kClassIID)) {
|
|
*aInstancePtr = (void*) (nsXPButton *)this;
|
|
AddRef();
|
|
return NS_OK;
|
|
}
|
|
if (aIID.Equals(kCIXPButtonIID)) {
|
|
*aInstancePtr = (void*) (nsIXPButton *)this;
|
|
AddRef();
|
|
return NS_OK;
|
|
}
|
|
if (aIID.Equals(kISupportsIID)) {
|
|
*aInstancePtr = (void*) (this);
|
|
AddRef();
|
|
return NS_OK;
|
|
}
|
|
return (nsXPItem::QueryInterface(aIID, aInstancePtr));
|
|
}
|
|
|
|
NS_IMPL_ADDREF(nsXPButton)
|
|
NS_IMPL_RELEASE(nsXPButton)
|
|
|
|
nsresult nsXPButton :: Init()
|
|
{
|
|
|
|
nsresult res = nsXPItem::Init();
|
|
|
|
LoadView(kViewCID);
|
|
|
|
return res;
|
|
}
|
|
|
|
nsresult nsXPButton :: SetParameter(nsString& aKey, nsString& aValue)
|
|
{
|
|
if (aKey.EqualsIgnoreCase(XPFC_STRING_MINIHOVERIMAGE)) {
|
|
|
|
CreateImageGroup();
|
|
|
|
mMiniHoverImageRequest = RequestImage(aValue);
|
|
|
|
} else if (aKey.EqualsIgnoreCase(XPFC_STRING_FULLHOVERIMAGE)) {
|
|
|
|
CreateImageGroup();
|
|
|
|
mFullHoverImageRequest = RequestImage(aValue);
|
|
|
|
} else if (aKey.EqualsIgnoreCase(XPFC_STRING_MINIPRESSEDIMAGE)) {
|
|
|
|
CreateImageGroup();
|
|
|
|
mMiniPressedImageRequest = RequestImage(aValue);
|
|
|
|
} else if (aKey.EqualsIgnoreCase(XPFC_STRING_FULLPRESSEDIMAGE)) {
|
|
|
|
CreateImageGroup();
|
|
|
|
mFullPressedImageRequest = RequestImage(aValue);
|
|
|
|
} else if (aKey.EqualsIgnoreCase(XPFC_STRING_COMMAND)) {
|
|
|
|
// XXX: Hardcoded to LoadUrl?
|
|
nsString command;
|
|
|
|
aValue.Mid(command,8,aValue.Length()-8);
|
|
|
|
SetCommand(command);
|
|
|
|
//} else if (aKey.EqualsIgnoreCase(XPFC_STRING_ENABLE)) {
|
|
|
|
|
|
} else {
|
|
|
|
return (nsXPItem::SetParameter(aKey, aValue));
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
nsresult nsXPButton :: GetClassPreferredSize(nsSize& aSize)
|
|
{
|
|
aSize.width = DEFAULT_WIDTH;
|
|
aSize.height = DEFAULT_HEIGHT;
|
|
return (NS_OK);
|
|
}
|
|
|
|
nsresult nsXPButton :: CreateView()
|
|
{
|
|
nsresult res = NS_OK;
|
|
return res;
|
|
}
|
|
|
|
nsresult nsXPButton :: SetLabel(nsString& aString)
|
|
{
|
|
nsXPItem::SetLabel(aString);
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult nsXPButton :: SetBounds(const nsRect &aBounds)
|
|
{
|
|
return (nsXPItem::SetBounds(aBounds));
|
|
}
|
|
|
|
nsEventStatus nsXPButton :: OnPaint(nsIRenderingContext& aRenderingContext,
|
|
const nsRect& aDirtyRect)
|
|
{
|
|
PushState(aRenderingContext);
|
|
PaintBackground(aRenderingContext,aDirtyRect);
|
|
PaintForeground(aRenderingContext,aDirtyRect);
|
|
PopState(aRenderingContext);
|
|
|
|
return nsEventStatus_eConsumeNoDefault;
|
|
}
|
|
|
|
|
|
nsEventStatus nsXPButton :: PaintBackground(nsIRenderingContext& aRenderingContext,
|
|
const nsRect& aDirtyRect)
|
|
{
|
|
|
|
nsRect rect;
|
|
nsIImage * img = nsnull;
|
|
|
|
GetBounds(rect);
|
|
|
|
if (mShowImage == eShowImage_none)
|
|
{
|
|
aRenderingContext.SetColor(GetBackgroundColor());
|
|
aRenderingContext.FillRect(rect);
|
|
return nsEventStatus_eConsumeNoDefault;
|
|
}
|
|
|
|
|
|
switch(mShowImage)
|
|
{
|
|
case eShowImage_mini:
|
|
if ((mState & eButtonState_pressed) && (mMiniPressedImageRequest != nsnull))
|
|
img = mMiniPressedImageRequest->GetImage();
|
|
else if ((mState & eButtonState_hover) && (mMiniHoverImageRequest != nsnull))
|
|
img = mMiniHoverImageRequest->GetImage();
|
|
|
|
if ((img == nsnull) && (mMiniImageRequest != nsnull))
|
|
img = mMiniImageRequest->GetImage();
|
|
break;
|
|
|
|
case eShowImage_full:
|
|
if ((mState & eButtonState_pressed) && (mFullPressedImageRequest != nsnull))
|
|
img = mFullPressedImageRequest->GetImage();
|
|
else if ((mState & eButtonState_hover) && (mFullHoverImageRequest != nsnull))
|
|
img = mFullHoverImageRequest->GetImage();
|
|
|
|
if ((img == nsnull) && (mFullImageRequest != nsnull))
|
|
img = mFullImageRequest->GetImage();
|
|
break;
|
|
|
|
}
|
|
|
|
if (img == nsnull)
|
|
{
|
|
aRenderingContext.SetColor(GetBackgroundColor());
|
|
aRenderingContext.FillRect(rect);
|
|
}
|
|
else
|
|
{
|
|
aRenderingContext.DrawImage(img, rect.x, rect.y);
|
|
}
|
|
|
|
|
|
NS_IF_RELEASE(img);
|
|
|
|
return nsEventStatus_eConsumeNoDefault;
|
|
}
|
|
|
|
nsEventStatus nsXPButton :: PaintForeground(nsIRenderingContext& aRenderingContext,
|
|
const nsRect& aDirtyRect)
|
|
{
|
|
if (mShowText == eShowText_none)
|
|
return nsEventStatus_eConsumeNoDefault;
|
|
|
|
// XXX: We really need to query system-wide colors via gfx system manager here?
|
|
// On windows, the calls are:
|
|
//
|
|
// GetSysColor(COLOR_BTNFACE), GetSysColor(COLOR_GRAYTEXT), GetSysColor(COLOR_GRAYTEXT)
|
|
|
|
if ((mState & eButtonState_hover))
|
|
aRenderingContext.SetColor(NS_RGB(64, 128, 192));
|
|
else
|
|
aRenderingContext.SetColor(GetForegroundColor());
|
|
|
|
// Draw text based on justifications
|
|
|
|
nsRect bounds;
|
|
nscoord x, y;
|
|
nscoord string_height, string_width;
|
|
nsString string = GetLabel();
|
|
|
|
GetBounds(bounds);
|
|
|
|
/*
|
|
* compute the Metrics for the string
|
|
*/
|
|
|
|
aRenderingContext.GetFontMetrics()->GetHeight(string_height);
|
|
aRenderingContext.GetWidth(string,string_width);
|
|
|
|
switch(mVerticalJustification)
|
|
{
|
|
|
|
case eTextJustification_top:
|
|
y = bounds.y;
|
|
break;
|
|
|
|
case eTextJustification_bottom:
|
|
y = bounds.y + bounds.height - string_height;
|
|
break;
|
|
|
|
default:
|
|
y = ((bounds.height - string_height)>>1)+bounds.y;
|
|
break;
|
|
|
|
}
|
|
|
|
switch(mHorizontalJustification)
|
|
{
|
|
|
|
case eTextJustification_left:
|
|
x = bounds.x;
|
|
break;
|
|
|
|
case eTextJustification_right:
|
|
x = bounds.x + bounds.width - string_width;
|
|
break;
|
|
|
|
default:
|
|
x = ((bounds.width - string_width)>>1)+bounds.x;
|
|
break;
|
|
|
|
}
|
|
|
|
aRenderingContext.DrawString(string,x,y,0);
|
|
|
|
return nsEventStatus_eConsumeNoDefault;
|
|
}
|
|
|
|
nsEventStatus nsXPButton::OnMouseMove(nsGUIEvent *aEvent)
|
|
{
|
|
return (nsXPItem::OnMouseMove(aEvent));
|
|
}
|
|
|
|
nsEventStatus nsXPButton::OnMouseEnter(nsGUIEvent *aEvent)
|
|
{
|
|
mState |= eButtonState_hover;
|
|
|
|
if (gXPFCToolkit->GetCanvasManager()->GetPressedCanvas() == ((nsIXPFCCanvas *)this))
|
|
mState |= eButtonState_pressed;
|
|
|
|
nsRect bounds;
|
|
|
|
GetView()->GetBounds(bounds);
|
|
|
|
// XXX: Need to convert coordinates to local views space.
|
|
// this means that GetBounds needs to look 'up' the
|
|
// view tree to figure out what view this canvas belongs
|
|
// to and convert thusly.
|
|
//
|
|
// Alternatively, we could just give every canvas a view...
|
|
//
|
|
bounds.x = 0;
|
|
bounds.y = 0;
|
|
|
|
gXPFCToolkit->GetViewManager()->UpdateView(GetView(), bounds, NS_VMREFRESH_AUTO_DOUBLE_BUFFER | NS_VMREFRESH_NO_SYNC);
|
|
return (nsXPItem::OnMouseEnter(aEvent));
|
|
}
|
|
|
|
nsEventStatus nsXPButton::OnMouseExit(nsGUIEvent *aEvent)
|
|
{
|
|
mState &= ~eButtonState_hover;
|
|
mState &= ~eButtonState_pressed;
|
|
nsRect bounds;
|
|
|
|
GetView()->GetBounds(bounds);
|
|
bounds.x = 0;
|
|
bounds.y = 0;
|
|
gXPFCToolkit->GetViewManager()->UpdateView(GetView(), bounds, NS_VMREFRESH_AUTO_DOUBLE_BUFFER | NS_VMREFRESH_NO_SYNC);
|
|
return (nsXPItem::OnMouseExit(aEvent));
|
|
}
|
|
|
|
nsEventStatus nsXPButton :: OnLeftButtonDown(nsGUIEvent *aEvent)
|
|
{
|
|
mState |= eButtonState_pressed;
|
|
nsRect bounds;
|
|
|
|
GetView()->GetBounds(bounds);
|
|
bounds.x = 0;
|
|
bounds.y = 0;
|
|
gXPFCToolkit->GetViewManager()->UpdateView(GetView(), bounds, NS_VMREFRESH_AUTO_DOUBLE_BUFFER | NS_VMREFRESH_NO_SYNC);
|
|
return (nsXPItem::OnLeftButtonDown(aEvent));
|
|
}
|
|
|
|
nsEventStatus nsXPButton :: OnLeftButtonUp(nsGUIEvent *aEvent)
|
|
{
|
|
mState &= ~eButtonState_pressed;
|
|
nsRect bounds;
|
|
|
|
GetView()->GetBounds(bounds);
|
|
bounds.x = 0;
|
|
bounds.y = 0;
|
|
gXPFCToolkit->GetViewManager()->UpdateView(GetView(), bounds, NS_VMREFRESH_AUTO_DOUBLE_BUFFER | NS_VMREFRESH_NO_SYNC);
|
|
|
|
SendCommand();
|
|
|
|
return (nsXPItem::OnLeftButtonUp(aEvent));
|
|
}
|
|
|