1 /////////////////////////////////////////////////////////////////////////////
 
   2 // Name:        cocoa/radiobut.mm
 
   3 // Purpose:     wxRadioButton
 
   4 // Author:      David Elliott
 
   8 // Copyright:   (c) 2003 David Elliott
 
   9 // Licence:     wxWidgets licence
 
  10 /////////////////////////////////////////////////////////////////////////////
 
  12 #include "wx/wxprec.h"
 
  19     #include "wx/radiobut.h"
 
  22 #import <AppKit/NSButton.h>
 
  23 #include "wx/cocoa/string.h"
 
  24 #include "wx/cocoa/autorelease.h"
 
  26 #include "wx/listimpl.cpp"
 
  28 WX_DEFINE_LIST(wxRadioButtonList);
 
  30 IMPLEMENT_DYNAMIC_CLASS(wxRadioButton, wxControl)
 
  31 // wxRadioButtonBase == wxControl
 
  32 BEGIN_EVENT_TABLE(wxRadioButton, wxControl)
 
  34 WX_IMPLEMENT_COCOA_OWNER(wxRadioButton,NSButton,NSControl,NSView)
 
  36 bool wxRadioButton::Create(wxWindow *parent, wxWindowID winid,
 
  37            const wxString& label,
 
  41            const wxValidator& validator,
 
  44     wxAutoNSAutoreleasePool pool;
 
  46     if(!CreateControl(parent,winid,pos,size,style,validator,name))
 
  51         m_radioSlaves.Append(this);
 
  53     else if(style&wxRB_SINGLE)
 
  57         for(wxWindowList::compatibility_iterator siblingNode= GetParent()->GetChildren().GetLast();
 
  59             siblingNode = siblingNode->GetPrevious())
 
  61             wxRadioButton *radioButton  = wxDynamicCast(siblingNode->GetData(),wxRadioButton);
 
  62             if(radioButton && radioButton!=this)
 
  64                 m_radioMaster = radioButton->m_radioMaster;
 
  65                 wxASSERT_MSG(m_radioMaster,
 
  66                     wxT("Previous radio button should be part of a group"));
 
  67                 // Don't crash, assume user meant wxRB_SINGLE
 
  69                     m_radioMaster->m_radioSlaves.Append(this);
 
  76     SetNSButton([[NSButton alloc] initWithFrame: MakeDefaultNSRect(size)]);
 
  77     [m_cocoaNSView release];
 
  78     [GetNSButton() setButtonType: NSRadioButton];
 
  79     [GetNSButton() setTitle:wxNSStringWithWxString(label)];
 
  80     // If it's the first in a group, it should be selected
 
  82         [GetNSButton() setState: NSOnState];
 
  83     [GetNSControl() sizeToFit];
 
  86         m_parent->CocoaAddChild(this);
 
  87     SetInitialFrameRect(pos,size);
 
  92 wxRadioButton::~wxRadioButton()
 
  94     if(m_radioMaster==this)
 
  96         // First get rid of ourselves (we should ALWAYS be at the head)
 
  97         wxRadioButtonList::compatibility_iterator slaveNode =
 
  98             m_radioSlaves.GetFirst();
 
 100         wxASSERT(slaveNode->GetData() == this);
 
 101         m_radioSlaves.Erase(slaveNode);
 
 103         // Now find the new master
 
 104         wxRadioButton *newMaster = NULL;
 
 105         slaveNode = m_radioSlaves.GetFirst();
 
 107             newMaster = slaveNode->GetData();
 
 109         // For each node (including the new master) set the master, remove
 
 110         // it from this list, and add it to the new master's list
 
 111         for(; slaveNode; slaveNode = m_radioSlaves.GetFirst())
 
 113             wxRadioButton *radioButton = slaveNode->GetData();
 
 114             wxASSERT(radioButton->m_radioMaster == this);
 
 115             radioButton->m_radioMaster = newMaster;
 
 116             newMaster->m_radioSlaves.Append(radioButton);
 
 117             m_radioSlaves.Erase(slaveNode);
 
 120     else if(m_radioMaster)
 
 122         m_radioMaster->m_radioSlaves.DeleteObject(this);
 
 123         m_radioMaster = NULL;
 
 126     DisassociateNSButton(GetNSButton());
 
 129 void wxRadioButton::SetValue(bool value)
 
 132         [GetNSButton() setState: NSOnState];
 
 134         [GetNSButton() setState: NSOffState];
 
 137 bool wxRadioButton::GetValue() const
 
 139     int state = [GetNSButton() state];
 
 140     wxASSERT(state!=NSMixedState);
 
 141     return state==NSOnState;
 
 144 void wxRadioButton::Cocoa_wxNSButtonAction(void)
 
 146     wxLogTrace(wxTRACE_COCOA,wxT("wxRadioButton"));
 
 147     if(m_radioMaster && ([GetNSButton() state] == NSOnState))
 
 149         for(wxRadioButtonList::compatibility_iterator slaveNode =
 
 150                 m_radioMaster->m_radioSlaves.GetFirst();
 
 151             slaveNode; slaveNode = slaveNode->GetNext())
 
 153             wxRadioButton *radioButton = slaveNode->GetData();
 
 154             if(radioButton!=this)
 
 155                 radioButton->SetValue(false);
 
 158     wxCommandEvent event(wxEVT_COMMAND_RADIOBUTTON_SELECTED, GetId());
 
 159     InitCommandEvent(event); //    event.SetEventObject(this);
 
 160     event.SetInt(GetValue());