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