]> git.saurik.com Git - wxWidgets.git/blame - src/cocoa/slider.mm
check that the version of __sync_sub_and_fetch that returns a value is supported...
[wxWidgets.git] / src / cocoa / slider.mm
CommitLineData
2ec55dc0 1/////////////////////////////////////////////////////////////////////////////
f4da9a94 2// Name: src/cocoa/slider.mm
2ec55dc0
DE
3// Purpose: wxSlider
4// Author: David Elliott
ddac39da 5// Mark Oxenham
2ec55dc0
DE
6// Modified by:
7// Created: 2003/06/19
8// RCS-ID: $Id$
9// Copyright: (c) 2003 David Elliott
ddac39da 10// (c) 2007 Software 2000 Ltd.
f4da9a94 11// Licence: wxWidgets licence
2ec55dc0
DE
12/////////////////////////////////////////////////////////////////////////////
13
449c5673 14#include "wx/wxprec.h"
f4da9a94 15
ef3e4a2c
DE
16#if wxUSE_SLIDER
17
f4da9a94
WS
18#include "wx/slider.h"
19
449c5673
DE
20#ifndef WX_PRECOMP
21 #include "wx/app.h"
449c5673 22#endif //WX_PRECOMP
2ec55dc0 23
4f46c20b 24#import <Foundation/NSString.h>
90f6792f 25#include "wx/cocoa/objc/NSSlider.h"
4f46c20b
DE
26#import <AppKit/NSEvent.h>
27#import <AppKit/NSWindow.h>
2ec55dc0
DE
28
29IMPLEMENT_DYNAMIC_CLASS(wxSlider, wxControl)
f4da9a94 30 BEGIN_EVENT_TABLE(wxSlider, wxSliderBase)
2ec55dc0 31END_EVENT_TABLE()
ddac39da
DE
32WX_IMPLEMENT_COCOA_OWNER(wxSlider,NSSlider,NSControl,NSView)
33
34
35inline void AdjustDimension(
36 bool isTicksStyle,
37 int &pos,
38 wxSize &size,
39 int (wxSize::*GetDimension)() const,
40 void (wxSize::*SetDimension)(int))
41{
42 const int dimension = (size.*GetDimension)();
43 const int minSize = (isTicksStyle) ? 23 : 20;
44
780220b0 45 // prevent clipping of overly "thin" sliders
ddac39da
DE
46 if (dimension < minSize)
47 {
48 (size.*SetDimension)(minSize);
49 }
50
780220b0
DE
51 // move the slider control to the middle of the dimension that is not
52 // being used to define its length
ddac39da
DE
53 pos += (dimension - (size.*GetDimension)() + 1) / 2;
54}
2ec55dc0
DE
55
56bool wxSlider::Create(wxWindow *parent, wxWindowID winid,
57 int value, int minValue, int maxValue,
58 const wxPoint& pos, const wxSize& size, long style,
59 const wxValidator& validator, const wxString& name)
60{
ddac39da
DE
61 wxSize adjustedSize(size);
62 wxPoint adjustedPos(pos);
63 const bool isTicksStyle = (style & wxSL_TICKS) != 0;
64
65 if ((style & wxSL_HORIZONTAL) && (size.GetHeight() != wxDefaultCoord))
66 {
67 AdjustDimension(isTicksStyle, adjustedPos.y, adjustedSize, &wxSize::GetHeight, &wxSize::SetHeight);
68 }
69 else if ((style & wxSL_VERTICAL) && (size.GetWidth() != wxDefaultCoord))
70 {
71 AdjustDimension(isTicksStyle, adjustedPos.x, adjustedSize, &wxSize::GetWidth, &wxSize::SetWidth);
72 }
73
780220b0 74 if(!CreateControl(parent,winid,adjustedPos,adjustedSize,style,validator,name))
2ec55dc0 75 return false;
780220b0 76 SetNSSlider([[WX_GET_OBJC_CLASS(WXNSSlider) alloc] initWithFrame: MakeDefaultNSRect(adjustedSize)]);
2ec55dc0 77 [m_cocoaNSView release];
ddac39da 78
2ec55dc0
DE
79 if(m_parent)
80 m_parent->CocoaAddChild(this);
780220b0 81 SetInitialFrameRect(adjustedPos,adjustedSize);
ddac39da
DE
82
83 SetRange(minValue, maxValue);
84 SetValue(value);
780220b0
DE
85
86 // -1 default for wxSL_AUTOTICKS == false
87 int tickMarks = -1;
88 // minValue > maxValue not handled, tickMarks set to 0
89 if ( style & wxSL_AUTOTICKS )
90 tickMarks = ((maxValue - minValue >= 0) ? (maxValue - minValue) : 0);
91 // arg2 needed a value, doesnt do anything
92 SetTickFreq(tickMarks,1);
8d656ea9 93
2ec55dc0
DE
94 return true;
95}
96
97wxSlider::~wxSlider()
98{
ddac39da
DE
99 DisassociateNSSlider(GetNSSlider());
100}
101
4f46c20b
DE
102void wxSlider::AssociateNSSlider(WX_NSSlider theSlider)
103{
104 wxCocoaNSSlider::AssociateNSSlider(theSlider);
105 // Set the target/action.. we don't really need to unset these
106 [theSlider setTarget:wxCocoaNSControl::sm_cocoaTarget];
107 [theSlider setAction:@selector(wxNSControlAction:)];
108}
109
ddac39da
DE
110void wxSlider::ProcessEventType(wxEventType commandType)
111{
112 wxScrollEvent event(commandType, GetId(), GetValue(), HasFlag(wxSL_VERTICAL)?wxVERTICAL:wxHORIZONTAL);
113 event.SetEventObject(this);
937013e0 114 HandleWindowEvent(event);
ddac39da
DE
115}
116
4f46c20b
DE
117static inline wxEventType wxSliderEventTypeForKeyFromEvent(NSEvent *theEvent)
118{
119 NSString *theEventCharacters = [theEvent charactersIgnoringModifiers];
120
121 if ([theEventCharacters length] == 1)
122 {
123 switch ([theEventCharacters characterAtIndex:0])
124 {
125 case NSUpArrowFunctionKey:
126 case NSRightArrowFunctionKey: return wxEVT_SCROLL_PAGEDOWN;
127 case NSDownArrowFunctionKey:
128 case NSLeftArrowFunctionKey: return wxEVT_SCROLL_PAGEUP;
129 case NSPageUpFunctionKey: return wxEVT_SCROLL_BOTTOM;
130 case NSPageDownFunctionKey: return wxEVT_SCROLL_TOP;
131 }
132 }
133 // Overload wxEVT_ANY to mean we can't determine the event type.
134 return wxEVT_ANY;
135}
136
137void wxSlider::CocoaTarget_action()
138{
139 wxEventType sliderEventType;
140 SEL theSelector = wxCocoaNSSlider::GetLastResponderSelector();
141
142 if( theSelector == @selector(moveUp:)
143 || theSelector == @selector(moveRight:))
144 sliderEventType = wxEVT_SCROLL_PAGEDOWN;
145 else if( theSelector == @selector(moveDown:)
146 || theSelector == @selector(moveLeft:))
147 sliderEventType = wxEVT_SCROLL_PAGEUP;
148 else if( theSelector == @selector(pageUp:))
149 sliderEventType = wxEVT_SCROLL_BOTTOM;
150 else if( theSelector == @selector(pageDown:))
151 sliderEventType = wxEVT_SCROLL_TOP;
152 else if( theSelector == @selector(keyDown:))
153 // This case should ideally never be reached.
154 sliderEventType = wxSliderEventTypeForKeyFromEvent([[GetNSSlider() window] currentEvent]);
155 else
156 // Don't generate an event.
157 return;
158 if(sliderEventType != wxEVT_ANY)
159 ProcessEventType(sliderEventType);
160}
161
ddac39da
DE
162void wxSlider::CocoaNotification_startTracking(WX_NSNotification notification)
163{
164 CocoaNotification_continueTracking(notification);
165}
166
167void wxSlider::CocoaNotification_continueTracking(WX_NSNotification notification)
168{
169 const double realValue = [GetNSSlider() doubleValue];
170
171 if (realValue != [GetNSSlider() intValue])
172 {
173 SetValue(rint(realValue));
174 }
175
176 ProcessEventType(wxEVT_SCROLL_THUMBTRACK);
177}
178
179void wxSlider::CocoaNotification_stopTracking(WX_NSNotification notification)
180{
181 ProcessEventType(wxEVT_SCROLL_THUMBRELEASE);
182}
183
184int wxSlider::GetValue() const
185{
186 return [GetNSSlider() intValue];
187}
188
189void wxSlider::SetValue(int value)
190{
191 [GetNSSlider() setIntValue:value];
192}
193
194void wxSlider::SetRange(int minValue, int maxValue)
195{
196 [GetNSSlider() setMinValue:minValue];
197 [GetNSSlider() setMaxValue:maxValue];
198}
199
200int wxSlider::GetMin() const
201{
202 return [GetNSSlider() minValue];
203}
204
205int wxSlider::GetMax() const
206{
207 return [GetNSSlider() maxValue];
208}
209
210void wxSlider::SetTickFreq(int n, int pos)
211{
212 const int numTicks = (n > 0) ? ((GetMax() - GetMin()) / n) + 1 : 0;
213 [GetNSSlider() setNumberOfTickMarks:numTicks];
214}
215
216int wxSlider::GetTickFreq() const
217{
218 const int numTicks = [GetNSSlider() numberOfTickMarks];
219 return ((numTicks != 0) ? (GetMax() - GetMin()) / (numTicks - 1) : 0);
220}
221
222void wxSlider::SetTickPos(int pos)
223{
224 NSTickMarkPosition thePos = NSTickMarkBelow;
225 wxSize size = GetSize();
226
227 if (size.GetWidth() < size.GetHeight()) // NSSlider isVertical method can return -1 if it has not been displayed.
228 {
229 thePos = (pos != 1) ? NSTickMarkLeft : NSTickMarkRight;
230 }
231 else
232 {
233 thePos = (pos != 1) ? NSTickMarkBelow : NSTickMarkAbove;
234 }
235
236 [GetNSSlider() setTickMarkPosition:thePos];
237}
238
239void wxSlider::SetLineSize(int lineSize)
240{
241 // to do
242}
243
244void wxSlider::SetPageSize(int pageSize)
245{
246 // to do
247}
248
249int wxSlider::GetLineSize() const
250{
251 return 1;
252}
253
254int wxSlider::GetPageSize() const
255{
256 return 1;
257}
258
259int wxSlider::GetThumbLength() const
260{
261 return 1;
262}
263
264void wxSlider::SetThumbLength(int lenPixels)
265{
266 // to do
2ec55dc0
DE
267}
268
ef3e4a2c 269#endif // wxUSE_SLIDER