]> git.saurik.com Git - wxWidgets.git/blame - src/cocoa/scrolbar.mm
Fix crash in wxDC::GetMultiLineTextExtent() after last commit.
[wxWidgets.git] / src / cocoa / scrolbar.mm
CommitLineData
5369a054 1/////////////////////////////////////////////////////////////////////////////
851dee09 2// Name: src/cocoa/scrolbar.mm
5369a054
DE
3// Purpose: wxScrollBar
4// Author: David Elliott
bd555421 5// Modified by: Mark Oxenham
5369a054
DE
6// Created: 2004/04/25
7// RCS-ID: $Id$
8// Copyright: (c) 2004 David Elliott
851dee09 9// Licence: wxWindows licence
5369a054
DE
10/////////////////////////////////////////////////////////////////////////////
11
12#include "wx/wxprec.h"
851dee09 13
5369a054
DE
14#if wxUSE_SCROLLBAR
15
851dee09
WS
16#include "wx/scrolbar.h"
17
5369a054
DE
18#ifndef WX_PRECOMP
19 #include "wx/app.h"
5369a054
DE
20#endif //WX_PRECOMP
21
22#import <AppKit/NSScroller.h>
23
5369a054
DE
24BEGIN_EVENT_TABLE(wxScrollBar, wxScrollBarBase)
25END_EVENT_TABLE()
26WX_IMPLEMENT_COCOA_OWNER(wxScrollBar,NSScroller,NSControl,NSView)
27
bd555421
DE
28inline NSControlSize AdjustDimension(
29 int &pos,
30 wxSize &size,
31 int (wxSize::*GetDimension)() const,
32 void (wxSize::*SetDimension)(int))
33{
34 NSControlSize controlSize = NSRegularControlSize;
35 const int dimension = (size.*GetDimension)();
36
37 if ((size.GetHeight() == -1) || (size.GetWidth() == -1) || (dimension >= 15))
38 {
39 (size.*SetDimension)(15);
40 }
41 else
42 {
43 (size.*SetDimension)(11);
44 controlSize = NSSmallControlSize;
45 }
46
47 pos += (dimension - (size.*GetDimension)() + 1) / 2;
48
49 return (controlSize);
50}
51
5369a054
DE
52bool wxScrollBar::Create(wxWindow *parent, wxWindowID winid,
53 const wxPoint& pos, const wxSize& size, long style,
54 const wxValidator& validator, const wxString& name)
55{
bd555421
DE
56 NSControlSize controlSize = NSRegularControlSize;
57 wxSize adjustedSize(size);
58 wxPoint adjustedPos(pos);
59
60 if ((style & wxSB_HORIZONTAL) && ((size.GetHeight() != wxDefaultCoord) || (size.GetHeight() == -1)))
61 {
62 controlSize = AdjustDimension(adjustedPos.y, adjustedSize, &wxSize::GetHeight, &wxSize::SetHeight);
63 }
64 else if ((style & wxSB_VERTICAL) && (size.GetWidth() != wxDefaultCoord || (size.GetWidth() == -1)))
65 {
66 controlSize = AdjustDimension(adjustedPos.x, adjustedSize, &wxSize::GetWidth, &wxSize::SetWidth);
67 }
68
69 if(!CreateControl(parent,winid,adjustedPos,adjustedSize,style,validator,name))
5369a054 70 return false;
bd555421 71 SetNSScroller([[NSScroller alloc] initWithFrame: MakeDefaultNSRect(adjustedSize)]);
5369a054
DE
72 [m_cocoaNSView release];
73 if(m_parent)
74 m_parent->CocoaAddChild(this);
bd555421
DE
75 SetInitialFrameRect(adjustedPos,adjustedSize);
76
77 BOOL nsEnabled = [GetNSScroller() isEnabled];
78
79 if (IsEnabled() != (nsEnabled != NO))
80 {
81 [GetNSScroller() setEnabled: !nsEnabled];
82 }
83
84 [GetNSScroller() setControlSize: controlSize];
5369a054
DE
85
86 return true;
87}
88
89wxScrollBar::~wxScrollBar()
90{
91 DisassociateNSScroller(GetNSScroller());
92}
93
94/* A word about NSScroller vs. wxScrollbar:
95
96NSScroller uses two float values to represent the state of the scroller.
97The floatValue indicates where the knob is positioned on a scale from
980.0 to 1.0. A value of 0.0 indicates the scroller is at the top or left,
99a value of 1.0 indicates the scroller is at the bottom or right. A value
100of 0.5 indicates the scroller is dead center.
101
102wxScrollBar uses three values. The position indicates the number of
103scroll units where 0 is at the top or left. The range indicates how
104many scroll units there are in the entire bar and the thumb size indicates
105how many scroll units the thumb takes. The scrollbar is at the bottom
106or right when position == range - thumbSize.
107
108It may be easier to consider wx position to be the top or left of the thumb.
109In Cocoa, floatValue can be considered as if it were the center of the
110thumb and the range is ALWAYS (no matter what the knobProportion is) the
111distance between the center point of the knob from one extreme to the other.
112*/
113
114int wxScrollBar::GetThumbPosition() const
115{
116 return (int)((m_range-m_thumbSize)*[GetNSScroller() floatValue]);
117}
118
119void wxScrollBar::SetThumbPosition(int position)
120{
121 [GetNSScroller() setFloatValue:((float)position)/(m_range-m_thumbSize)];
122}
123
124void wxScrollBar::SetScrollbar(int position, int thumbSize,
125 int range, int pageSize, bool refresh)
126{
127 m_range = range;
128 m_thumbSize = thumbSize;
129 m_pageSize = pageSize;
130 [GetNSScroller() setFloatValue:((float)position)/(m_range-m_thumbSize)
131 knobProportion:((float)m_thumbSize)/m_range];
132}
133
134void wxScrollBar::Cocoa_wxNSScrollerAction()
135{
136 NSScrollerPart hitPart = [GetNSScroller() hitPart];
137 wxEventType command;
138 // Note: the comments about the part that is hit are for OS X, the
139 // constants are sort of a leftover from NeXT. It makes more sense if
140 // you remember that in NeXT clicking the knob slot used to do what
141 // option-clicking does now.
142 switch(hitPart)
143 {
144 // User dragged knob
145 case NSScrollerKnob:
146 command = wxEVT_SCROLL_THUMBTRACK;
147 break;
148 // User option-clicked slot
149 case NSScrollerKnobSlot:
150 command = wxEVT_SCROLL_THUMBTRACK;
151 break;
152 // User clicked Up/Left button
153 case NSScrollerDecrementLine:
154 command = wxEVT_SCROLL_LINEUP;
155 break;
156 // User option-clicked Up/left or clicked in slot
157 case NSScrollerDecrementPage:
158 command = wxEVT_SCROLL_PAGEUP;
159 break;
160 // User clicked Down/Right button
161 case NSScrollerIncrementLine:
162 command = wxEVT_SCROLL_LINEDOWN;
163 break;
164 // User option-clicked Down/Right or clicked in slot
165 case NSScrollerIncrementPage:
166 command = wxEVT_SCROLL_PAGEDOWN;
167 break;
168 // No-op
169 case NSScrollerNoPart:
170 default:
171 return;
172 }
173 // TODO: When scrolling by pages, readjust the floatValue using the
174 // pageSize (which may be different from thumbSize).
175 wxScrollEvent event(command, GetId(), GetThumbPosition(),
176 HasFlag(wxSB_VERTICAL)?wxVERTICAL:wxHORIZONTAL);
177 event.SetEventObject(this);
937013e0 178 HandleWindowEvent(event);
5369a054
DE
179}
180
181#endif // wxUSE_SCROLLBAR