blob: b07e05588449e424c584e4843e29ab5f89ff69e0 [file] [log] [blame]
/*
* Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import "config.h"
#import "PlatformScrollBar.h"
#import "BlockExceptions.h"
using namespace WebCore;
@interface WebCoreScrollBar : NSScroller
{
PlatformScrollbar* scrollbar;
}
- (id)initWithPlatformScrollbar:(PlatformScrollbar*)s;
- (void)detachPlatformScrollbar;
@end
@implementation WebCoreScrollBar
static NSControlSize NSControlSizeForScrollBarControlSize(ScrollbarControlSize size)
{
if (size == SmallScrollbar)
return NSSmallControlSize;
if (size == MiniScrollbar)
return NSMiniControlSize;
return NSRegularControlSize;
}
- (id)initWithPlatformScrollbar:(PlatformScrollbar*)s
{
// Cocoa scrollbars just set their orientation by examining their own
// dimensions, so we have to do this unsavory hack.
NSRect orientation;
NSControlSize controlSize = NSControlSizeForScrollBarControlSize(s->controlSize());
orientation.origin.x = orientation.origin.y = 0;
if (s->orientation() == VerticalScrollbar) {
orientation.size.width = [NSScroller scrollerWidthForControlSize:controlSize];
orientation.size.height = 100;
} else {
orientation.size.width = 100;
orientation.size.height = [NSScroller scrollerWidthForControlSize:controlSize];
}
self = [self initWithFrame:orientation];
scrollbar = s;
[self setEnabled:YES];
[self setTarget:self];
[self setAction:@selector(scroll:)];
[self setControlSize:controlSize];
return self;
}
- (void)detachPlatformScrollbar
{
[self setTarget:nil];
scrollbar = 0;
}
- (IBAction)scroll:(NSScroller*)sender
{
if (scrollbar)
scrollbar->scrollbarHit([sender hitPart]);
}
- (void)mouseDown:(NSEvent *)event
{
Widget::beforeMouseDown(self, scrollbar);
[super mouseDown:event];
Widget::afterMouseDown(self, scrollbar);
}
@end
namespace WebCore
{
PlatformScrollbar::PlatformScrollbar(ScrollbarClient* client, ScrollbarOrientation orientation, ScrollbarControlSize controlSize)
: Scrollbar(client, orientation, controlSize)
{
BEGIN_BLOCK_OBJC_EXCEPTIONS;
WebCoreScrollBar *bar = [[WebCoreScrollBar alloc] initWithPlatformScrollbar:this];
setView(bar);
[bar release];
END_BLOCK_OBJC_EXCEPTIONS;
}
PlatformScrollbar::~PlatformScrollbar()
{
WebCoreScrollBar* bar = (WebCoreScrollBar*)getView();
[bar detachPlatformScrollbar];
// Widget should probably do this for all widgets.
// But we don't need it for form elements, and for frames it doesn't work
// well because of the way the NSViews are created in WebKit. So for now,
// we'll just do it explictly for Scrollbar.
removeFromSuperview();
}
void PlatformScrollbar::updateThumbPosition()
{
BEGIN_BLOCK_OBJC_EXCEPTIONS;
WebCoreScrollBar *bar = (WebCoreScrollBar *)getView();
[bar setFloatValue:(float)m_currentPos / (m_totalSize - m_visibleSize)
knobProportion:[bar knobProportion]];
END_BLOCK_OBJC_EXCEPTIONS;
}
void PlatformScrollbar::updateThumbProportion()
{
float val = static_cast<float>(m_visibleSize) / m_totalSize;
BEGIN_BLOCK_OBJC_EXCEPTIONS;
WebCoreScrollBar *bar = (WebCoreScrollBar *)getView();
if (val != [bar knobProportion] && val >= 0)
[bar setFloatValue:static_cast<float>(m_currentPos) / (m_totalSize - m_visibleSize) knobProportion:val];
END_BLOCK_OBJC_EXCEPTIONS;
}
bool PlatformScrollbar::scrollbarHit(NSScrollerPart hitPart)
{
int maxPos = m_totalSize - m_visibleSize;
if (maxPos <= 0)
return false; // Impossible to scroll anywhere.
WebCoreScrollBar *bar = (WebCoreScrollBar *)getView();
int newPos = value();
switch (hitPart) {
case NSScrollerDecrementLine:
newPos -= m_lineStep;
break;
case NSScrollerIncrementLine:
newPos += m_lineStep;
break;
case NSScrollerDecrementPage:
newPos -= m_pageStep;
break;
case NSScrollerIncrementPage:
newPos += m_pageStep;
break;
// If the thumb is hit, then the scrollbar changed its value for us.
case NSScrollerKnob:
case NSScrollerKnobSlot:
newPos = (int)([bar floatValue] * maxPos);
break;
case NSScrollerNoPart:
break;
}
return setValue(newPos);
}
int PlatformScrollbar::width() const
{
return Widget::width();
}
int PlatformScrollbar::height() const
{
return Widget::height();
}
void PlatformScrollbar::setRect(const IntRect& rect)
{
setFrameGeometry(rect);
}
void PlatformScrollbar::setEnabled(bool enabled)
{
Widget::setEnabled(enabled);
}
void PlatformScrollbar::paint(GraphicsContext* graphicsContext, const IntRect& damageRect)
{
Widget::paint(graphicsContext, damageRect);
}
}