Merged trunk 47523, 47567, 47569 (full wxRadioBox implementation):
* Partially implement wxRadioBox for wxCocoa. * Implement most of wxRadioBox's methods. * Implement wxCocoa wxRadioBox event. Copyright 2007 Software 2000 Ltd. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_8_BRANCH@47573 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -13,6 +13,7 @@
|
|||||||
#define __WX_COCOA_RADIOBOX_H__
|
#define __WX_COCOA_RADIOBOX_H__
|
||||||
|
|
||||||
// #include "wx/cocoa/NSButton.h"
|
// #include "wx/cocoa/NSButton.h"
|
||||||
|
DECLARE_WXCOCOA_OBJC_CLASS(NSMatrix);
|
||||||
|
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
// wxRadioBox
|
// wxRadioBox
|
||||||
@@ -21,7 +22,9 @@ class WXDLLEXPORT wxRadioBox: public wxControl, public wxRadioBoxBase// , protec
|
|||||||
{
|
{
|
||||||
DECLARE_DYNAMIC_CLASS(wxRadioBox)
|
DECLARE_DYNAMIC_CLASS(wxRadioBox)
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
// WX_DECLARE_COCOA_OWNER(NSButton,NSControl,NSView)
|
// NOTE: We explicitly skip NSControl because our primary cocoa view is
|
||||||
|
// the NSBox but we want to receive action messages from the NSMatrix.
|
||||||
|
WX_DECLARE_COCOA_OWNER(NSBox,NSView,NSView)
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// initialization
|
// initialization
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
@@ -92,6 +95,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
// Static boxes cannot be enabled/disabled
|
// Static boxes cannot be enabled/disabled
|
||||||
virtual void CocoaSetEnabled(bool enable) { }
|
virtual void CocoaSetEnabled(bool enable) { }
|
||||||
|
virtual void CocoaTarget_action(void);
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// Implementation
|
// Implementation
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
@@ -106,7 +110,29 @@ public:
|
|||||||
virtual void SetString(unsigned int n, const wxString& label);
|
virtual void SetString(unsigned int n, const wxString& label);
|
||||||
// change the individual radio button state
|
// change the individual radio button state
|
||||||
protected:
|
protected:
|
||||||
|
// We don't want the typical wxCocoaNSBox behavior because our real
|
||||||
|
// implementation is by using an NSMatrix as the NSBox's contentView.
|
||||||
|
WX_NSMatrix GetNSMatrix() const;
|
||||||
|
void AssociateNSBox(WX_NSBox theBox);
|
||||||
|
void DisassociateNSBox(WX_NSBox theBox);
|
||||||
|
|
||||||
virtual wxSize DoGetBestSize() const;
|
virtual wxSize DoGetBestSize() const;
|
||||||
|
|
||||||
|
int GetRowForIndex(int n) const
|
||||||
|
{
|
||||||
|
if(m_windowStyle & wxRA_SPECIFY_COLS)
|
||||||
|
return n / GetMajorDim();
|
||||||
|
else
|
||||||
|
return n % GetMajorDim();
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetColumnForIndex(int n) const
|
||||||
|
{
|
||||||
|
if(m_windowStyle & wxRA_SPECIFY_COLS)
|
||||||
|
return n % GetMajorDim();
|
||||||
|
else
|
||||||
|
return n / GetMajorDim();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __WX_COCOA_RADIOBOX_H__
|
#endif // __WX_COCOA_RADIOBOX_H__
|
||||||
|
@@ -6,6 +6,7 @@
|
|||||||
// Created: 2003/02/15
|
// Created: 2003/02/15
|
||||||
// RCS-ID: $Id$
|
// RCS-ID: $Id$
|
||||||
// Copyright: (c) 2003 David Elliott
|
// Copyright: (c) 2003 David Elliott
|
||||||
|
// (c) 2007 Software 2000 Ltd.
|
||||||
// Licence: wxWidgets licence
|
// Licence: wxWidgets licence
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -20,12 +21,34 @@
|
|||||||
#include "wx/arrstr.h"
|
#include "wx/arrstr.h"
|
||||||
#endif //WX_PRECOMP
|
#endif //WX_PRECOMP
|
||||||
|
|
||||||
|
#include "wx/cocoa/string.h"
|
||||||
|
#include "wx/cocoa/autorelease.h"
|
||||||
|
|
||||||
#include "wx/cocoa/objc/NSView.h"
|
#include "wx/cocoa/objc/NSView.h"
|
||||||
|
#import <AppKit/NSButton.h>
|
||||||
|
#import <AppKit/NSBox.h>
|
||||||
|
#import <AppKit/NSMatrix.h>
|
||||||
|
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxRadioBox, wxControl)
|
IMPLEMENT_DYNAMIC_CLASS(wxRadioBox, wxControl)
|
||||||
BEGIN_EVENT_TABLE(wxRadioBox, wxControl)
|
BEGIN_EVENT_TABLE(wxRadioBox, wxControl)
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
// WX_IMPLEMENT_COCOA_OWNER(wxRadioBox,NSTextField,NSControl,NSView)
|
|
||||||
|
void wxRadioBox::AssociateNSBox(WX_NSBox cocoaObjcClass)
|
||||||
|
{
|
||||||
|
NSMatrix *radioBox = [(WX_NSBox)cocoaObjcClass contentView];
|
||||||
|
// Associate the NSMatrix (the NSBox's contentView) with the wxCocoaNSControl MI base class.
|
||||||
|
AssociateNSControl(radioBox);
|
||||||
|
// Set the target/action.. we don't really need to unset these
|
||||||
|
[radioBox setTarget:wxCocoaNSControl::sm_cocoaTarget];
|
||||||
|
[radioBox setAction:@selector(wxNSControlAction:)];
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxRadioBox::DisassociateNSBox(WX_NSBox cocoaObjcClass)
|
||||||
|
{
|
||||||
|
DisassociateNSControl([(WX_NSBox)cocoaObjcClass contentView]);
|
||||||
|
}
|
||||||
|
|
||||||
|
WX_IMPLEMENT_COCOA_OWNER(wxRadioBox,NSBox,NSView,NSView)
|
||||||
|
|
||||||
bool wxRadioBox::Create(wxWindow *parent, wxWindowID winid,
|
bool wxRadioBox::Create(wxWindow *parent, wxWindowID winid,
|
||||||
const wxString& title,
|
const wxString& title,
|
||||||
@@ -51,62 +74,198 @@ bool wxRadioBox::Create(wxWindow *parent, wxWindowID winid,
|
|||||||
long style, const wxValidator& validator,
|
long style, const wxValidator& validator,
|
||||||
const wxString& name)
|
const wxString& name)
|
||||||
{
|
{
|
||||||
|
// We autorelease heavily so we want our own pool
|
||||||
|
wxAutoNSAutoreleasePool pool;
|
||||||
|
|
||||||
if(!CreateControl(parent,winid,pos,size,style,validator,name))
|
if(!CreateControl(parent,winid,pos,size,style,validator,name))
|
||||||
return false;
|
return false;
|
||||||
SetNSView([[WX_GET_OBJC_CLASS(WXNSView) alloc] initWithFrame: MakeDefaultNSRect(size)]);
|
|
||||||
[m_cocoaNSView release];
|
majorDim = majorDim == 0 ? n : majorDim;
|
||||||
|
// TODO: Don't forget to call SetMajorDim
|
||||||
|
// We can't yet as we can't implement GetCount() until after
|
||||||
|
// we make the NSMatrix.
|
||||||
|
int minorDim = (n + majorDim - 1) / majorDim;
|
||||||
|
|
||||||
|
|
||||||
|
// Create a prototype cell for use with the NSMatrix build
|
||||||
|
NSCell *currCell = [[NSButtonCell alloc] initTextCell:@""];
|
||||||
|
[(NSButtonCell*)currCell setButtonType:NSRadioButton];
|
||||||
|
|
||||||
|
// Build up an array of all cells plus any extra empty cells
|
||||||
|
NSMutableArray *allCells = [NSMutableArray arrayWithCapacity:n];
|
||||||
|
for(int i=0; i<n; ++i)
|
||||||
|
{
|
||||||
|
[currCell setTitle: wxNSStringWithWxString(wxStripMenuCodes(choices[i], wxStrip_Mnemonics))];
|
||||||
|
[allCells addObject: currCell];
|
||||||
|
[currCell release];
|
||||||
|
// NOTE: We can still safely message currCell as the array has retained it.
|
||||||
|
currCell = [currCell copy];
|
||||||
|
}
|
||||||
|
[currCell release];
|
||||||
|
|
||||||
|
// NOTE: Although an image cell with no image is documented to return NSZeroSize from
|
||||||
|
// the cellSize method, the documentation is WRONG. It will actually return a huge size
|
||||||
|
// (thousands) which makes every cell in the matrix that big. Not good.
|
||||||
|
// Be safe and initialize a text cell with an empty string. That always works.
|
||||||
|
currCell = [[NSCell alloc] initTextCell:@""];
|
||||||
|
[currCell setEnabled:NO]; // Don't allow user to select this cell
|
||||||
|
for(int i=n; i < majorDim * minorDim; ++i)
|
||||||
|
{
|
||||||
|
[allCells addObject: currCell];
|
||||||
|
// NOTE: Use the same instance.. this should work and save some heap allocations.
|
||||||
|
#if 0
|
||||||
|
[currCell release];
|
||||||
|
currCell = [currCell copy];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
[currCell release];
|
||||||
|
currCell = NULL;
|
||||||
|
|
||||||
|
// Although the documentation on addColumnWithCells:/addRowWithCells: explicitly
|
||||||
|
// states that it will determine the initial dimension upon the first call if
|
||||||
|
// the initial size is 0x0 it LIES. It will fail an assertion in the code
|
||||||
|
// if you use the simpler initWithFrame: initializer.
|
||||||
|
// Therefore, we specify the major dimension and leave the minor dimension as 0
|
||||||
|
// so that we can add the rows/columns without failing the assertion.
|
||||||
|
NSMatrix* radioBox = [[NSMatrix alloc]
|
||||||
|
initWithFrame:NSZeroRect
|
||||||
|
mode:NSRadioModeMatrix
|
||||||
|
cellClass:nil
|
||||||
|
numberOfRows:style&wxRA_SPECIFY_COLS?0:majorDim
|
||||||
|
numberOfColumns:style&wxRA_SPECIFY_COLS?majorDim:0
|
||||||
|
];
|
||||||
|
|
||||||
|
SEL addMajorWithCellsSelector;
|
||||||
|
// If column count is the major dimension then we add by row
|
||||||
|
if( style & wxRA_SPECIFY_COLS )
|
||||||
|
addMajorWithCellsSelector = @selector(addRowWithCells:);
|
||||||
|
// If row count is the major dimension then we add by column
|
||||||
|
else
|
||||||
|
addMajorWithCellsSelector = @selector(addColumnWithCells:);
|
||||||
|
|
||||||
|
for(int i=0; i<minorDim; ++i)
|
||||||
|
{
|
||||||
|
[radioBox
|
||||||
|
performSelector:addMajorWithCellsSelector
|
||||||
|
withObject:[allCells subarrayWithRange:NSMakeRange(i*majorDim, majorDim)]];
|
||||||
|
}
|
||||||
|
|
||||||
|
NSBox *theBox = [[NSBox alloc] initWithFrame:MakeDefaultNSRect(size)];
|
||||||
|
|
||||||
|
// Replace the box's content view with the NSMatrix we just created
|
||||||
|
// IMPORTANT: This must be done before calling SetNSBox.
|
||||||
|
[theBox setContentView:radioBox];
|
||||||
|
[radioBox release]; // The NSBox retains it for us.
|
||||||
|
|
||||||
|
SetNSBox(theBox);
|
||||||
|
[theBox release];
|
||||||
|
|
||||||
|
|
||||||
|
[GetNSBox() setTitle:wxNSStringWithWxString(wxStripMenuCodes(title, wxStrip_Mnemonics))];
|
||||||
|
// [GetNSBox() setBorderType:NSLineBorder]; // why??
|
||||||
|
|
||||||
|
SetMajorDim(majorDim, style);
|
||||||
|
|
||||||
if(m_parent)
|
if(m_parent)
|
||||||
m_parent->CocoaAddChild(this);
|
m_parent->CocoaAddChild(this);
|
||||||
SetInitialFrameRect(pos,size);
|
|
||||||
|
// Do the sizer dance
|
||||||
|
[GetNSBox() sizeToFit];
|
||||||
|
SetInitialFrameRect(pos, size);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxRadioBox::~wxRadioBox()
|
wxRadioBox::~wxRadioBox()
|
||||||
{
|
{
|
||||||
|
DisassociateNSBox(GetNSBox());
|
||||||
|
}
|
||||||
|
|
||||||
|
WX_NSMatrix wxRadioBox::GetNSMatrix() const
|
||||||
|
{
|
||||||
|
return (NSMatrix*)[(NSBox*)m_cocoaNSView contentView];
|
||||||
}
|
}
|
||||||
|
|
||||||
// selection
|
// selection
|
||||||
void wxRadioBox::SetSelection(int n)
|
void wxRadioBox::SetSelection(int n)
|
||||||
{
|
{
|
||||||
|
int r = GetRowForIndex(n);
|
||||||
|
int c = GetColumnForIndex(n);
|
||||||
|
[GetNSMatrix() selectCellAtRow:r column:c];
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxRadioBox::GetSelection() const
|
int wxRadioBox::GetSelection() const
|
||||||
{
|
{
|
||||||
return 0;
|
NSMatrix *radioBox = GetNSMatrix();
|
||||||
|
NSInteger r = [radioBox selectedRow];
|
||||||
|
NSInteger c = [radioBox selectedColumn];
|
||||||
|
if(m_windowStyle & wxRA_SPECIFY_COLS)
|
||||||
|
return r * GetMajorDim() + c;
|
||||||
|
else
|
||||||
|
return c * GetMajorDim() + r;
|
||||||
}
|
}
|
||||||
|
|
||||||
// string access
|
// string access
|
||||||
unsigned int wxRadioBox::GetCount() const
|
unsigned int wxRadioBox::GetCount() const
|
||||||
{
|
{
|
||||||
return 0;
|
NSMatrix *radioBox = GetNSMatrix();
|
||||||
|
NSInteger rowCount, columnCount;
|
||||||
|
[radioBox getNumberOfRows:&rowCount columns:&columnCount];
|
||||||
|
|
||||||
|
// FIXME: This is wrong if padding cells were made
|
||||||
|
return rowCount * columnCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString wxRadioBox::GetString(unsigned int n) const
|
wxString wxRadioBox::GetString(unsigned int n) const
|
||||||
{
|
{
|
||||||
return wxEmptyString;
|
int r = GetRowForIndex(n);
|
||||||
|
int c = GetColumnForIndex(n);
|
||||||
|
// FIXME: Cocoa stores the mnemonic-stripped title.
|
||||||
|
return wxStringWithNSString([[GetNSMatrix() cellAtRow:r column:c] title]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxRadioBox::SetString(unsigned int n, const wxString& label)
|
void wxRadioBox::SetString(unsigned int n, const wxString& label)
|
||||||
{
|
{
|
||||||
|
int r = GetRowForIndex(n);
|
||||||
|
int c = GetColumnForIndex(n);
|
||||||
|
[[GetNSMatrix() cellAtRow:r column:c] setTitle:wxNSStringWithWxString(wxStripMenuCodes(label, wxStrip_Mnemonics))];
|
||||||
}
|
}
|
||||||
|
|
||||||
// change the individual radio button state
|
// change the individual radio button state
|
||||||
bool wxRadioBox::Enable(unsigned int n, bool enable)
|
bool wxRadioBox::Enable(unsigned int n, bool enable)
|
||||||
{
|
{
|
||||||
// TODO
|
int r = GetRowForIndex(n);
|
||||||
return false;
|
int c = GetColumnForIndex(n);
|
||||||
|
NSCell *cell = [GetNSMatrix() cellAtRow:r column:c];
|
||||||
|
if(cell == nil)
|
||||||
|
return false;
|
||||||
|
bool wasEnabled = [cell isEnabled];
|
||||||
|
[cell setEnabled:enable];
|
||||||
|
return (wasEnabled && !enable) || (!wasEnabled && enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxRadioBox::Show(unsigned int n, bool show)
|
bool wxRadioBox::Show(unsigned int n, bool show)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
|
// NOTE: Cocoa has no visible state for cells so we'd need to replace the
|
||||||
|
// cell with a dummy one to hide it or alternatively subclass NSButtonCell
|
||||||
|
// and add the behavior.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxSize wxRadioBox::DoGetBestSize() const
|
wxSize wxRadioBox::DoGetBestSize() const
|
||||||
{
|
{
|
||||||
return wxSize(50,50);
|
// The NSBox responds to sizeToFit by sending sizeToFit to its contentView
|
||||||
|
// which is the NSMatrix and does the right thing.
|
||||||
|
return wxControl::DoGetBestSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxRadioBox::CocoaTarget_action(void)
|
||||||
|
{
|
||||||
|
wxCommandEvent event(wxEVT_COMMAND_RADIOBOX_SELECTED, GetId());
|
||||||
|
InitCommandEvent(event);
|
||||||
|
event.SetInt(GetSelection()); // i.e. SetSelection.
|
||||||
|
Command(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user