Files
Mozilla/mozilla/widget/src/xlib/nsScrollBar.cpp
dmose%mozilla.org 92d791b7b0 updated license boilerplate to xPL 1.1, a=chofmann@netscape.com,r=endico@mozilla.org
git-svn-id: svn://10.0.0.236/trunk@52908 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-06 03:40:37 +00:00

423 lines
12 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsScrollBar.h"
#include "nsGfxCIID.h"
#include "xlibrgb.h"
NS_IMPL_ADDREF(nsScrollbar)
NS_IMPL_RELEASE(nsScrollbar)
PRLogModuleInfo *XlibScrollbarLM = PR_NewLogModule("XlibScrollbar");
nsScrollbar::nsScrollbar(PRBool aIsVertical) : nsWidget(), nsIScrollbar()
{
NS_INIT_REFCNT();
mMaxRange = 0;
mPosition = 0;
mThumbSize = 0;
mLineIncrement = 1;
mIsVertical = aIsVertical;
mBackground = NS_RGB(100,100,100);
mBackgroundPixel = xlib_rgb_xpixel_from_rgb(mBackground);
mBorderPixel = xlib_rgb_xpixel_from_rgb(mBackground);
mBar = 0;
mBarBounds.x = mBarBounds.y = mBarBounds.width = mBarBounds.height = 0;
};
nsScrollbar::~nsScrollbar()
{
if (mBar) {
XDestroyWindow(mDisplay, mBar);
DeleteWindowCallback(mBar);
}
}
nsresult nsScrollbar::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
nsresult result = nsWidget::QueryInterface(aIID, aInstancePtr);
static NS_DEFINE_IID(kInsScrollbarIID, NS_ISCROLLBAR_IID);
if (result == NS_NOINTERFACE && aIID.Equals(kInsScrollbarIID)) {
*aInstancePtr = (void*) ((nsIScrollbar*)this);
NS_ADDREF_THIS();
result = NS_OK;
}
return result;
}
NS_METHOD nsScrollbar::SetMaxRange(PRUint32 aEndRange)
{
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("nsScrollbar::SetMaxRange()\n"));
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("Max Range set to %d\n", aEndRange));
mMaxRange = aEndRange;
CalcBarBounds();
LayoutBar();
return NS_OK;
}
PRUint32 nsScrollbar::GetMaxRange(PRUint32& aRange)
{
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("nsScrollbar::GetMaxRange()\n"));
aRange = mMaxRange;
return NS_OK;
}
NS_METHOD nsScrollbar::SetPosition(PRUint32 aPos)
{
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("nsScrollbar::SetPosition()\n"));
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("Scroll to %d\n", aPos));
mPosition = aPos;
CalcBarBounds();
LayoutBar();
return NS_OK;
}
PRUint32 nsScrollbar::GetPosition(PRUint32& aPosition)
{
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("nsScrollbar::GetPosition()\n"));
aPosition = mPosition;
return NS_OK;
}
NS_METHOD nsScrollbar::SetThumbSize(PRUint32 aSize)
{
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("nsScrollbar::SetThumbSize()\n"));
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("Thumb size set to %d\n", aSize));
mThumbSize = aSize;
CalcBarBounds();
LayoutBar();
return NS_OK;
}
NS_METHOD nsScrollbar::GetThumbSize(PRUint32& aSize)
{
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("nsScrollbar::GetThumbSize()\n"));
aSize = mThumbSize;
return NS_OK;
}
NS_METHOD nsScrollbar::SetLineIncrement(PRUint32 aSize)
{
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("nsScrollbar::SetLineIncrement()\n"));
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("Set Line Increment to %d\n", aSize));
mLineIncrement = aSize;
CalcBarBounds();
LayoutBar();
return NS_OK;
}
NS_METHOD nsScrollbar::GetLineIncrement(PRUint32& aSize)
{
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("nsScrollbar::GetLineIncrement()\n"));
aSize = mLineIncrement;
return NS_OK;
}
NS_METHOD nsScrollbar::SetParameters(PRUint32 aMaxRange, PRUint32 aThumbSize,
PRUint32 aPosition, PRUint32 aLineIncrement)
{
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("nsScrollbar::SetParameters()\n"));
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("MaxRange = %d ThumbSize = %d aPosition = %d LineIncrement = %d\n",
aMaxRange, aThumbSize, aPosition, aLineIncrement));
SetMaxRange(aMaxRange);
SetThumbSize(aThumbSize);
SetPosition(aPosition);
SetLineIncrement(aLineIncrement);
CalcBarBounds();
LayoutBar();
return NS_OK;
}
PRBool nsScrollbar::OnScroll(PRUint32 scrollCode, int cPos)
{
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("nsScrollbar::OnScroll\n"));
PRBool result = PR_FALSE;
switch (scrollCode) {
case NS_SCROLLBAR_PAGE_NEXT:
result = NextPage();
break;
case NS_SCROLLBAR_PAGE_PREV:
result = PrevPage();
break;
default:
break;
}
return result;
}
PRBool nsScrollbar::OnResize(nsSizeEvent &event)
{
PRBool result;
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("nsScrollbar::OnResize\n"));
nsWidget::OnResize(event);
CalcBarBounds();
LayoutBar();
result = PR_FALSE;
return result;
}
PRBool nsScrollbar::DispatchMouseEvent(nsMouseEvent &aEvent)
{
PRBool result;
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("nsScrollbar::DispatchMouseEvent\n"));
// check to see if this was on the main window.
switch (aEvent.message) {
case NS_MOUSE_LEFT_BUTTON_DOWN:
if (mIsVertical == PR_TRUE) {
if (aEvent.point.y < mBarBounds.y) {
OnScroll(NS_SCROLLBAR_PAGE_PREV, 0);
}
else if (aEvent.point.y > mBarBounds.height) {
OnScroll(NS_SCROLLBAR_PAGE_NEXT, 0);
}
}
else {
if (aEvent.point.x < mBarBounds.x) {
OnScroll(NS_SCROLLBAR_PAGE_PREV, 0);
}
else if (aEvent.point.x > mBarBounds.width) {
OnScroll(NS_SCROLLBAR_PAGE_NEXT, 0);
}
}
break;
default:
break;
}
result = PR_FALSE;
return result;
}
void nsScrollbar::CreateNative(Window aParent, nsRect aRect)
{
XSetWindowAttributes attr;
unsigned long attr_mask;
// on a window resize, we don't want to window contents to
// be discarded...
attr.bit_gravity = SouthEastGravity;
// make sure that we listen for events
attr.event_mask = StructureNotifyMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | FocusChangeMask | VisibilityChangeMask;
// set the default background color and border to that awful gray
attr.background_pixel = mBackgroundPixel;
attr.border_pixel = mBorderPixel;
// set the colormap
attr.colormap = xlib_rgb_get_cmap();
// here's what's in the struct
attr_mask = CWBitGravity | CWEventMask | CWBackPixel | CWBorderPixel;
// check to see if there was actually a colormap.
if (attr.colormap)
attr_mask |= CWColormap;
CreateNativeWindow(aParent, mBounds, attr, attr_mask);
CreateGC();
// set up the scrolling bar.
attr.event_mask = Button1MotionMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | FocusChangeMask | VisibilityChangeMask;
attr.background_pixel = xlib_rgb_xpixel_from_rgb(NS_RGB(192,192,192));
attr.border_pixel = xlib_rgb_xpixel_from_rgb(NS_RGB(100,100,100));
// set up the size
CalcBarBounds();
mBar = XCreateWindow(mDisplay,
mBaseWindow,
mBarBounds.x, mBarBounds.y,
mBarBounds.width, mBarBounds.height,
2, // border width
mDepth,
InputOutput,
mVisual,
attr_mask,
&attr);
AddWindowCallback(mBar, this);
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("nsScrollbar::CreateNative created window 0x%lx with bar 0x%lx\n",
mBaseWindow, mBar));
}
NS_IMETHODIMP nsScrollbar::Show(PRBool bState)
{
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("nsScrollbar::Show(): %s\n",
(bState == PR_TRUE) ? "true" : "false"));
nsWidget::Show(bState);
if (bState) {
if (mBar) {
XMapWindow(mDisplay, mBar);
}
CalcBarBounds();
LayoutBar();
}
return NS_OK;
}
NS_IMETHODIMP nsScrollbar::Resize(PRInt32 aWidth,
PRInt32 aHeight,
PRBool aRepaint)
{
nsWidget::Resize(aWidth, aHeight, aRepaint);
CalcBarBounds();
LayoutBar();
return NS_OK;
}
NS_IMETHODIMP nsScrollbar::Resize(PRInt32 aX,
PRInt32 aY,
PRInt32 aWidth,
PRInt32 aHeight,
PRBool aRepaint)
{
nsWidget::Resize(aX, aY, aWidth, aHeight, aRepaint);
CalcBarBounds();
LayoutBar();
return NS_OK;
}
nsresult nsScrollbar::NextPage(void)
{
PRUint32 max;
nsresult result = PR_FALSE;
// change it locally.
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("nsScrollbar::NextPage(): maxrange is %d thumb is %d position is %d\n", mMaxRange, mThumbSize, mPosition));
max = mMaxRange - mThumbSize;
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("nsScrollbar::NextPage(): max is %d\n", max));
mPosition += mThumbSize;
if (mPosition > max)
mPosition = max;
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("nsScrollbar::NextPage(): new position is %d\n", mPosition));
// send the event
if (mEventCallback) {
nsScrollbarEvent sevent;
sevent.message = NS_SCROLLBAR_POS;
sevent.widget = (nsWidget *)this;
sevent.eventStructType = NS_SCROLLBAR_EVENT;
sevent.position = (mPosition);
sevent.point.x = 0;
sevent.point.y = 0;
// send the event
result = ConvertStatus((*mEventCallback) (&sevent));
// the gtk code indicates that the callback can
// modify the position. how odd.
mPosition = sevent.position;
}
CalcBarBounds();
LayoutBar();
return result;
}
nsresult nsScrollbar::PrevPage(void)
{
nsresult result = PR_FALSE;
// check to make sure we don't go backwards
if (mThumbSize > mPosition) {
mPosition = 0;
}
else {
mPosition -= mThumbSize;
}
// send the event
if (mEventCallback) {
nsScrollbarEvent sevent;
sevent.message = NS_SCROLLBAR_POS;
sevent.widget = (nsWidget *)this;
sevent.eventStructType = NS_SCROLLBAR_EVENT;
sevent.position = (mPosition);
// send the event
result = ConvertStatus((*mEventCallback) (&sevent));
// the gtk code indicates that the callback can
// modify the position. how odd.
mPosition = sevent.position;
}
CalcBarBounds();
LayoutBar();
return result;
}
void nsScrollbar::CalcBarBounds(void)
{
float bar_start;
float bar_end;
if (mMaxRange == 0) {
bar_start = 0;
bar_end = 0;
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("CalcBarBounds: max range is zero.\n"));
}
else {
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("CalcBarBounds: position: %d max: %d thumb: %d\n",
mPosition, mMaxRange, mThumbSize));
bar_start = (float)mPosition / (float)mMaxRange;
bar_end = (float)mThumbSize / (float)mMaxRange;
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("CalcBarBounds: start: %f end: %f\n", bar_start, bar_end));
}
if (mIsVertical == PR_TRUE) {
mBarBounds.x = 0;
mBarBounds.y = (int)(bar_start * mRequestedSize.height);
mBarBounds.width = mRequestedSize.width;
mBarBounds.height = (int)(bar_end * mRequestedSize.height);
}
else {
mBarBounds.x = (int)(bar_start * mRequestedSize.width);
mBarBounds.y = 0;
mBarBounds.width = (int)(bar_end * mRequestedSize.width);
mBarBounds.height = mRequestedSize.height;
}
if (mBarBounds.height == 0) {
mBarBounds.height = 1;
}
if (mBarBounds.width == 0) {
mBarBounds.width = 1;
}
PR_LOG(XlibScrollbarLM, PR_LOG_DEBUG, ("CalcBarBounds: bar is (%s) %d %d %d %d\n",
((mIsVertical == PR_TRUE) ? "vertical" : "horizontal" ),
mBarBounds.x, mBarBounds.y, mBarBounds.width, mBarBounds.height));
}
void nsScrollbar::LayoutBar(void)
{
XMoveResizeWindow(mDisplay, mBar,
mBarBounds.x, mBarBounds.y,
mBarBounds.width, mBarBounds.height);
}
NS_IMETHODIMP nsScrollbar::Move(PRInt32 aX, PRInt32 aY)
{
return nsWidget::Move(aX, aY);
}