1 /////////////////////////////////////////////////////////////////////////////
 
   2 // Name:        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"
 
  17     #include "wx/scrolbar.h"
 
  20 #import <AppKit/NSScroller.h>
 
  22 IMPLEMENT_DYNAMIC_CLASS(wxScrollBar, wxControl)
 
  23 BEGIN_EVENT_TABLE(wxScrollBar, wxScrollBarBase)
 
  25 WX_IMPLEMENT_COCOA_OWNER(wxScrollBar,NSScroller,NSControl,NSView)
 
  27 bool wxScrollBar::Create(wxWindow *parent, wxWindowID winid,
 
  28             const wxPoint& pos, const wxSize& size, long style,
 
  29             const wxValidator& validator, const wxString& name)
 
  31     if(!CreateControl(parent,winid,pos,size,style,validator,name))
 
  33     SetNSScroller([[NSScroller alloc] initWithFrame: MakeDefaultNSRect(size)]);
 
  34     [m_cocoaNSView release];
 
  36         m_parent->CocoaAddChild(this);
 
  37     SetInitialFrameRect(pos,size);
 
  42 wxScrollBar::~wxScrollBar()
 
  44     DisassociateNSScroller(GetNSScroller());
 
  47 /* A word about NSScroller vs. wxScrollbar:
 
  49 NSScroller uses two float values to represent the state of the scroller.
 
  50 The floatValue indicates where the knob is positioned on a scale from
 
  51 0.0 to 1.0.  A value of 0.0 indicates the scroller is at the top or left,
 
  52 a value of 1.0 indicates the scroller is at the bottom or right.  A value
 
  53 of 0.5 indicates the scroller is dead center.
 
  55 wxScrollBar uses three values.  The position indicates the number of
 
  56 scroll units where 0 is at the top or left.  The range indicates how
 
  57 many scroll units there are in the entire bar and the thumb size indicates
 
  58 how many scroll units the thumb takes.  The scrollbar is at the bottom
 
  59 or right when position == range - thumbSize.
 
  61 It may be easier to consider wx position to be the top or left of the thumb.
 
  62 In Cocoa, floatValue can be considered as if it were the center of the
 
  63 thumb and the range is ALWAYS (no matter what the knobProportion is) the
 
  64 distance between the center point of the knob from one extreme to the other.
 
  67 int wxScrollBar::GetThumbPosition() const
 
  69     return (int)((m_range-m_thumbSize)*[GetNSScroller() floatValue]);
 
  72 void wxScrollBar::SetThumbPosition(int position)
 
  74     [GetNSScroller() setFloatValue:((float)position)/(m_range-m_thumbSize)];
 
  77 void wxScrollBar::SetScrollbar(int position, int thumbSize,
 
  78             int range, int pageSize, bool refresh)
 
  81     m_thumbSize = thumbSize;
 
  82     m_pageSize = pageSize;
 
  83     [GetNSScroller() setFloatValue:((float)position)/(m_range-m_thumbSize)
 
  84             knobProportion:((float)m_thumbSize)/m_range];
 
  87 void wxScrollBar::Cocoa_wxNSScrollerAction()
 
  89     NSScrollerPart hitPart = [GetNSScroller() hitPart];
 
  91     // Note: the comments about the part that is hit are for OS X, the
 
  92     // constants are sort of a leftover from NeXT.  It makes more sense if
 
  93     // you remember that in NeXT clicking the knob slot used to do what
 
  94     // option-clicking does now.
 
  99         command = wxEVT_SCROLL_THUMBTRACK;
 
 101     // User option-clicked slot
 
 102     case NSScrollerKnobSlot:
 
 103         command = wxEVT_SCROLL_THUMBTRACK;
 
 105     // User clicked Up/Left button
 
 106     case NSScrollerDecrementLine:
 
 107         command = wxEVT_SCROLL_LINEUP;
 
 109     // User option-clicked Up/left or clicked in slot
 
 110     case NSScrollerDecrementPage:
 
 111         command = wxEVT_SCROLL_PAGEUP;
 
 113     // User clicked Down/Right button
 
 114     case NSScrollerIncrementLine:
 
 115         command = wxEVT_SCROLL_LINEDOWN;
 
 117     // User option-clicked Down/Right or clicked in slot
 
 118     case NSScrollerIncrementPage:
 
 119         command = wxEVT_SCROLL_PAGEDOWN;
 
 122     case NSScrollerNoPart:
 
 126     // TODO: When scrolling by pages, readjust the floatValue using the
 
 127     // pageSize (which may be different from thumbSize).
 
 128     wxScrollEvent event(command, GetId(), GetThumbPosition(),
 
 129         HasFlag(wxSB_VERTICAL)?wxVERTICAL:wxHORIZONTAL);
 
 130     event.SetEventObject(this);
 
 131     GetEventHandler()->ProcessEvent(event);
 
 134 #endif // wxUSE_SCROLLBAR