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