1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/cocoa/scrolbar.mm
3 // Purpose: wxScrollBar
4 // Author: David Elliott
8 // Copyright: (c) 2004 David Elliott
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
16 #include "wx/scrolbar.h"
22 #import <AppKit/NSScroller.h>
24 IMPLEMENT_DYNAMIC_CLASS(wxScrollBar, wxControl)
25 BEGIN_EVENT_TABLE(wxScrollBar, wxScrollBarBase)
27 WX_IMPLEMENT_COCOA_OWNER(wxScrollBar,NSScroller,NSControl,NSView)
29 bool wxScrollBar::Create(wxWindow *parent, wxWindowID winid,
30 const wxPoint& pos, const wxSize& size, long style,
31 const wxValidator& validator, const wxString& name)
33 if(!CreateControl(parent,winid,pos,size,style,validator,name))
35 SetNSScroller([[NSScroller alloc] initWithFrame: MakeDefaultNSRect(size)]);
36 [m_cocoaNSView release];
38 m_parent->CocoaAddChild(this);
39 SetInitialFrameRect(pos,size);
44 wxScrollBar::~wxScrollBar()
46 DisassociateNSScroller(GetNSScroller());
49 /* A word about NSScroller vs. wxScrollbar:
51 NSScroller uses two float values to represent the state of the scroller.
52 The floatValue indicates where the knob is positioned on a scale from
53 0.0 to 1.0. A value of 0.0 indicates the scroller is at the top or left,
54 a value of 1.0 indicates the scroller is at the bottom or right. A value
55 of 0.5 indicates the scroller is dead center.
57 wxScrollBar uses three values. The position indicates the number of
58 scroll units where 0 is at the top or left. The range indicates how
59 many scroll units there are in the entire bar and the thumb size indicates
60 how many scroll units the thumb takes. The scrollbar is at the bottom
61 or right when position == range - thumbSize.
63 It may be easier to consider wx position to be the top or left of the thumb.
64 In Cocoa, floatValue can be considered as if it were the center of the
65 thumb and the range is ALWAYS (no matter what the knobProportion is) the
66 distance between the center point of the knob from one extreme to the other.
69 int wxScrollBar::GetThumbPosition() const
71 return (int)((m_range-m_thumbSize)*[GetNSScroller() floatValue]);
74 void wxScrollBar::SetThumbPosition(int position)
76 [GetNSScroller() setFloatValue:((float)position)/(m_range-m_thumbSize)];
79 void wxScrollBar::SetScrollbar(int position, int thumbSize,
80 int range, int pageSize, bool refresh)
83 m_thumbSize = thumbSize;
84 m_pageSize = pageSize;
85 [GetNSScroller() setFloatValue:((float)position)/(m_range-m_thumbSize)
86 knobProportion:((float)m_thumbSize)/m_range];
89 void wxScrollBar::Cocoa_wxNSScrollerAction()
91 NSScrollerPart hitPart = [GetNSScroller() hitPart];
93 // Note: the comments about the part that is hit are for OS X, the
94 // constants are sort of a leftover from NeXT. It makes more sense if
95 // you remember that in NeXT clicking the knob slot used to do what
96 // option-clicking does now.
101 command = wxEVT_SCROLL_THUMBTRACK;
103 // User option-clicked slot
104 case NSScrollerKnobSlot:
105 command = wxEVT_SCROLL_THUMBTRACK;
107 // User clicked Up/Left button
108 case NSScrollerDecrementLine:
109 command = wxEVT_SCROLL_LINEUP;
111 // User option-clicked Up/left or clicked in slot
112 case NSScrollerDecrementPage:
113 command = wxEVT_SCROLL_PAGEUP;
115 // User clicked Down/Right button
116 case NSScrollerIncrementLine:
117 command = wxEVT_SCROLL_LINEDOWN;
119 // User option-clicked Down/Right or clicked in slot
120 case NSScrollerIncrementPage:
121 command = wxEVT_SCROLL_PAGEDOWN;
124 case NSScrollerNoPart:
128 // TODO: When scrolling by pages, readjust the floatValue using the
129 // pageSize (which may be different from thumbSize).
130 wxScrollEvent event(command, GetId(), GetThumbPosition(),
131 HasFlag(wxSB_VERTICAL)?wxVERTICAL:wxHORIZONTAL);
132 event.SetEventObject(this);
133 GetEventHandler()->ProcessEvent(event);
136 #endif // wxUSE_SCROLLBAR