2 * Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #import "BlockExceptions.h"
32 #import "KeyboardEvent.h"
33 #import "WebCoreFrameBridge.h"
34 #import "WebCoreWidgetHolder.h"
35 #import "WidgetClient.h"
38 using namespace WebCore;
40 @interface WebCoreSlider : NSSlider <WebCoreWidgetHolder>
43 BOOL inNextValidKeyView;
46 - (id)initWithSlider:(Slider*)s;
51 @implementation WebCoreSlider
53 - (id)initWithSlider:(Slider*)s
59 [self setTarget:self];
60 [self setAction:@selector(slide:)];
61 [self setContinuous:YES]; // Our sliders are always continuous by default.
62 [self setMinValue:0.0];
63 [self setMaxValue:100.0];
64 [self setDoubleValue:50.0];
75 - (void)mouseDown:(NSEvent *)event
77 Widget::beforeMouseDown(self);
78 [super mouseDown:event];
79 Widget::afterMouseDown(self);
81 slider->sendConsumedMouseUp();
82 if (slider && slider->client())
83 slider->client()->clicked(slider);
86 - (IBAction)slide:(NSSlider*)sender
89 slider->sliderValueChanged();
97 // FIXME: All the firstResponder and keyView code here is replicated in KWQButton and
98 // other KWQ classes. We should find a way to share this code.
99 - (BOOL)becomeFirstResponder
101 BOOL become = [super becomeFirstResponder];
102 if (become && slider && slider->client()) {
103 if (!FrameMac::currentEventIsMouseDownInWidget(slider))
104 slider->client()->scrollToVisible(slider);
105 slider->client()->focusIn(slider);
106 [FrameMac::bridgeForWidget(slider) formControlIsBecomingFirstResponder:self];
111 - (BOOL)resignFirstResponder
113 BOOL resign = [super resignFirstResponder];
114 if (resign && slider && slider->client()) {
115 slider->client()->focusOut(slider);
116 [FrameMac::bridgeForWidget(slider) formControlIsResigningFirstResponder:self];
121 -(NSView *)nextKeyView
124 if (slider && inNextValidKeyView) {
125 // resign so we send a blur before setting focus on
126 // the next widget, otherwise the blur for this
127 // widget will remove focus from the widget after
129 [self resignFirstResponder];
131 view = FrameMac::nextKeyViewForWidget(slider, SelectingNext);
133 view = [super nextKeyView];
136 view = [super nextKeyView];
141 -(NSView *)previousKeyView
144 if (slider && inNextValidKeyView) {
145 // resign so we send a blur before setting focus on
146 // the next widget, otherwise the blur for this
147 // widget will remove focus from the widget after
149 [self resignFirstResponder];
151 view = FrameMac::nextKeyViewForWidget(slider, SelectingPrevious);
153 view = [super previousKeyView];
156 view = [super previousKeyView];
161 - (BOOL)canBecomeKeyView
163 // Simplified method from NSView; overridden to replace NSView's way of checking
164 // for full keyboard access with ours.
166 FrameMac* frame = Mac(Frame::frameForWidget(slider));
167 if (!frame->tabsToAllControls(frame->currentKeyboardEvent().get()))
170 return [self window] != nil && ![self isHiddenOrHasHiddenAncestor] && [self acceptsFirstResponder];
173 -(NSView *)nextValidKeyView
175 inNextValidKeyView = YES;
176 NSView *view = [super nextValidKeyView];
177 inNextValidKeyView = NO;
181 -(NSView *)previousValidKeyView
183 inNextValidKeyView = YES;
184 NSView *view = [super previousValidKeyView];
185 inNextValidKeyView = NO;
197 : m_minVal(0.0), m_maxVal(100.0), m_val(50.0)
199 BEGIN_BLOCK_OBJC_EXCEPTIONS;
200 WebCoreSlider* slider = [[WebCoreSlider alloc] initWithSlider:this];
201 [[slider cell] setControlSize:NSSmallControlSize];
204 END_BLOCK_OBJC_EXCEPTIONS;
209 WebCoreSlider* slider = (WebCoreSlider*)getView();
210 [slider detachSlider];
213 void Slider::setFont(const Font& f)
215 BEGIN_BLOCK_OBJC_EXCEPTIONS;
219 const NSControlSize size = ControlSizeForFont(f);
220 NSControl * const slider = static_cast<NSControl *>(getView());
221 [[slider cell] setControlSize:size];
222 [slider setFont:[NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:size]]];
224 END_BLOCK_OBJC_EXCEPTIONS;
227 Widget::FocusPolicy Slider::focusPolicy() const
229 BEGIN_BLOCK_OBJC_EXCEPTIONS;
231 FrameMac* frame = Mac(Frame::frameForWidget(this));
232 if (!frame || !frame->tabsToAllControls(frame->currentKeyboardEvent().get()))
235 END_BLOCK_OBJC_EXCEPTIONS;
237 return Widget::focusPolicy();
240 IntSize Slider::sizeHint() const
242 return IntSize(dimensions()[dimWidth], dimensions()[dimHeight]);
245 void Slider::setValue(double v)
247 double val = max(m_minVal, min(v, m_maxVal));
249 WebCoreSlider* slider = (WebCoreSlider*)getView();
250 [slider setDoubleValue: val];
254 void Slider::setMinValue(double v)
256 if (v == m_minVal) return;
258 WebCoreSlider* slider = (WebCoreSlider*)getView();
259 [slider setMinValue: v];
263 void Slider::setMaxValue(double v)
265 if (v == m_maxVal) return;
267 WebCoreSlider* slider = (WebCoreSlider*)getView();
268 [slider setMaxValue: v];
272 double Slider::value() const
277 double Slider::minValue() const
282 double Slider::maxValue() const
287 void Slider::sliderValueChanged()
289 WebCoreSlider* slider = (WebCoreSlider*)getView();
290 double v = [slider doubleValue];
294 client()->valueChanged(this);
298 const int* Slider::dimensions() const
300 // We empirically determined these dimensions.
301 // It would be better to get this info from AppKit somehow.
302 static const int w[3][2] = {
307 NSControl * const slider = static_cast<NSControl *>(getView());
309 BEGIN_BLOCK_OBJC_EXCEPTIONS;
310 return w[[[slider cell] controlSize]];
311 END_BLOCK_OBJC_EXCEPTIONS;
313 return w[NSSmallControlSize];