1/////////////////////////////////////////////////////////////////////////////
2// Name:        src/osx/cocoa/scrolbar.mm
3// Purpose:     wxScrollBar
4// Author:      Stefan Csomor
5// Modified by:
6// Created:     1998-01-01
7// Copyright:   (c) Stefan Csomor
8// Licence:       wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
11#include "wx/wxprec.h"
12
13#include "wx/scrolbar.h"
14
15#ifndef WX_PRECOMP
16    #include "wx/intl.h"
17    #include "wx/log.h"
18    #include "wx/settings.h"
19#endif
20
21#include "wx/math.h"
22#include "wx/osx/private.h"
23
24@interface wxNSScroller : NSScroller
25{
26}
27@end
28
29@implementation wxNSScroller
30
31+ (void)initialize
32{
33    static BOOL initialized = NO;
34    if (!initialized)
35    {
36        initialized = YES;
37        wxOSXCocoaClassAddWXMethods(self);
38    }
39}
40
41@end
42
43class wxOSXScrollBarCocoaImpl : public wxWidgetCocoaImpl
44{
45public :
46    wxOSXScrollBarCocoaImpl( wxWindowMac* peer, WXWidget w) : wxWidgetCocoaImpl( peer, w )
47    {
48        m_maximum = 1;
49    }
50
51    void SetMaximum(wxInt32 v)
52    {
53        m_maximum = (v == 0) ? 1 : v;
54    }
55
56    void    SetScrollThumb( wxInt32 value, wxInt32 thumbSize )
57    {
58        double v = ((double) value)/m_maximum;
59        double t = ((double) thumbSize)/(m_maximum+thumbSize);
60        [(wxNSScroller*) m_osxView setDoubleValue:v];
61        [(wxNSScroller*) m_osxView setKnobProportion:t];
62    }
63
64    virtual wxInt32 GetValue() const
65    {
66        return wxRound([(wxNSScroller*) m_osxView floatValue] * m_maximum);
67    }
68
69    virtual wxInt32 GetMaximum() const
70    {
71        return m_maximum;
72    }
73
74    virtual void controlAction(WXWidget slf, void* _cmd, void *sender);
75    virtual void mouseEvent(WX_NSEvent event, WXWidget slf, void* _cmd);
76protected:
77    wxInt32 m_maximum;
78};
79
80// we will have a mouseDown, then in the native
81// implementation of mouseDown the tracking code
82// is calling clickedAction, therefore we wire this
83// to thumbtrack and only after super mouseDown
84// returns we will call the thumbrelease
85
86void wxOSXScrollBarCocoaImpl::controlAction( WXWidget WXUNUSED(slf), void *WXUNUSED(_cmd), void *WXUNUSED(sender))
87{
88    wxEventType scrollEvent = wxEVT_NULL;
89    switch ([(NSScroller*)m_osxView hitPart])
90    {
91    case NSScrollerIncrementLine:
92        scrollEvent = wxEVT_SCROLL_LINEDOWN;
93        break;
94    case NSScrollerIncrementPage:
95        scrollEvent = wxEVT_SCROLL_PAGEDOWN;
96        break;
97    case NSScrollerDecrementLine:
98        scrollEvent = wxEVT_SCROLL_LINEUP;
99        break;
100    case NSScrollerDecrementPage:
101        scrollEvent = wxEVT_SCROLL_PAGEUP;
102        break;
103    case NSScrollerKnob:
104    case NSScrollerKnobSlot:
105        scrollEvent = wxEVT_SCROLL_THUMBTRACK;
106        break;
107    case NSScrollerNoPart:
108    default:
109        return;
110    }
111
112    wxWindow* wxpeer = (wxWindow*) GetWXPeer();
113    if ( wxpeer )
114        wxpeer->TriggerScrollEvent(scrollEvent);
115}
116
117void wxOSXScrollBarCocoaImpl::mouseEvent(WX_NSEvent event, WXWidget slf, void *_cmd)
118{
119    wxWidgetCocoaImpl::mouseEvent(event, slf, _cmd);
120
121    // send a release event in case we've been tracking the thumb
122    if ( strcmp( sel_getName((SEL) _cmd) , "mouseDown:") == 0 )
123    {
124        NSScrollerPart hit = [(NSScroller*)m_osxView hitPart];
125        if ( (hit == NSScrollerKnob || hit == NSScrollerKnobSlot) )
126        {
127            wxWindow* wxpeer = (wxWindow*) GetWXPeer();
128            if ( wxpeer )
129                wxpeer->OSXHandleClicked(0);
130        }
131    }
132}
133
134wxWidgetImplType* wxWidgetImpl::CreateScrollBar( wxWindowMac* wxpeer,
135                                    wxWindowMac* WXUNUSED(parent),
136                                    wxWindowID WXUNUSED(id),
137                                    const wxPoint& pos,
138                                    const wxSize& size,
139                                    long style,
140                                    long WXUNUSED(extraStyle))
141{
142    NSRect r = wxOSXGetFrameForControl( wxpeer, pos , size ) ;
143    // the creation rect defines the orientation
144    NSRect createRect = ( style & wxSB_HORIZONTAL ) ? NSMakeRect(r.origin.x, r.origin.y , 17, 16) :
145        NSMakeRect(r.origin.x, r.origin.y , 16, 17);
146    wxNSScroller* v = [[wxNSScroller alloc] initWithFrame:createRect];
147    [v setFrame:r];
148
149    wxWidgetCocoaImpl* c = new wxOSXScrollBarCocoaImpl( wxpeer, v );
150    [v setEnabled:YES];
151    return c;
152}
153