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