dolphin/Externals/wxWidgets3/src/osx/radiobox_osx.cpp
Soren Jorvang d14efe561b Import r67258 of the wxWidgets trunk, which I expect will before
long become wxWidgets 2.9.2, which in turn is expected to be the
last 2.9 release before the 3.0 stable release.

Since the full wxWidgets distribution is rather large, I have
imported only the parts that we use, on a subdirectory basis:

art
include/wx/*.*
include/wx/aui
include/wx/cocoa
include/wx/generic
include/wx/gtk
include/wx/meta
include/wx/msw
include/wx/osx
include/wx/persist
include/wx/private
include/wx/protocol
include/wx/unix
src/aui
src/common
src/generic
src/gtk
src/msw
src/osx
src/unix


git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7380 8ced0084-cf51-0410-be5f-012b33b47a6e
2011-03-20 18:05:19 +00:00

563 lines
13 KiB
C++

/////////////////////////////////////////////////////////////////////////////
// Name: src/osx/radiobox_osx.cpp
// Purpose: wxRadioBox
// Author: Stefan Csomor
// Modified by: JS Lair (99/11/15) first implementation
// Created: 1998-01-01
// RCS-ID: $Id: radiobox_osx.cpp 67254 2011-03-20 00:14:35Z DS $
// Copyright: (c) Stefan Csomor
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#include "wx/wxprec.h"
#if wxUSE_RADIOBOX
#include "wx/radiobox.h"
#ifndef WX_PRECOMP
#include "wx/radiobut.h"
#include "wx/arrstr.h"
#endif
#include "wx/osx/private.h"
// regarding layout: note that there are differences in inter-control
// spacing between InterfaceBuild and the Human Interface Guidelines, we stick
// to the latter, as those are also used eg in the System Preferences Dialogs
IMPLEMENT_DYNAMIC_CLASS(wxRadioBox, wxControl)
BEGIN_EVENT_TABLE(wxRadioBox, wxControl)
EVT_RADIOBUTTON( wxID_ANY , wxRadioBox::OnRadioButton )
END_EVENT_TABLE()
void wxRadioBox::OnRadioButton( wxCommandEvent &outer )
{
if ( outer.IsChecked() )
{
wxCommandEvent event( wxEVT_COMMAND_RADIOBOX_SELECTED, m_windowId );
int i = GetSelection() ;
event.SetInt(i);
event.SetString(GetString(i));
event.SetEventObject( this );
ProcessCommand(event);
}
}
wxRadioBox::wxRadioBox()
{
m_noItems = 0;
m_noRowsOrCols = 0;
m_radioButtonCycle = NULL;
}
wxRadioBox::~wxRadioBox()
{
SendDestroyEvent();
wxRadioButton *next, *current;
current = m_radioButtonCycle->NextInCycle();
if (current != NULL)
{
while (current != m_radioButtonCycle)
{
next = current->NextInCycle();
delete current;
current = next;
}
delete current;
}
}
// Create the radiobox for two-step construction
bool wxRadioBox::Create( wxWindow *parent,
wxWindowID id, const wxString& label,
const wxPoint& pos, const wxSize& size,
const wxArrayString& choices,
int majorDim, long style,
const wxValidator& val, const wxString& name )
{
wxCArrayString chs(choices);
return Create(
parent, id, label, pos, size, chs.GetCount(),
chs.GetStrings(), majorDim, style, val, name);
}
bool wxRadioBox::Create( wxWindow *parent,
wxWindowID id, const wxString& label,
const wxPoint& pos, const wxSize& size,
int n, const wxString choices[],
int majorDim, long style,
const wxValidator& val, const wxString& name )
{
DontCreatePeer();
if ( !wxControl::Create( parent, id, pos, size, style, val, name ) )
return false;
// during construction we must keep this at 0, otherwise GetBestSize fails
m_noItems = 0;
m_noRowsOrCols = majorDim;
m_radioButtonCycle = NULL;
SetMajorDim( majorDim == 0 ? n : majorDim, style );
m_labelOrig = m_label = label;
SetPeer(wxWidgetImpl::CreateGroupBox( this, parent, id, label, pos, size, style, GetExtraStyle() ));
for (int i = 0; i < n; i++)
{
wxRadioButton *radBtn = new wxRadioButton(
this,
wxID_ANY,
GetLabelText(choices[i]),
wxPoint( 5, 20 * i + 10 ),
wxDefaultSize,
i == 0 ? wxRB_GROUP : 0 );
if ( i == 0 )
m_radioButtonCycle = radBtn;
// m_radioButtonCycle = radBtn->AddInCycle( m_radioButtonCycle );
}
// as all radiobuttons have been set-up, set the correct dimensions
m_noItems = (unsigned int)n;
SetMajorDim( majorDim == 0 ? n : majorDim, style );
SetSelection( 0 );
InvalidateBestSize();
SetInitialSize( size );
MacPostControlCreate( pos, size );
return true;
}
// Enables or disables the entire radiobox
//
bool wxRadioBox::Enable(bool enable)
{
wxRadioButton *current;
if (!wxControl::Enable( enable ))
return false;
current = m_radioButtonCycle;
for (unsigned int i = 0; i < m_noItems; i++)
{
current->Enable( enable );
current = current->NextInCycle();
}
return true;
}
// Enables or disables an given button
//
bool wxRadioBox::Enable(unsigned int item, bool enable)
{
if (!IsValid( item ))
return false;
unsigned int i = 0;
wxRadioButton *current = m_radioButtonCycle;
while (i != item)
{
i++;
current = current->NextInCycle();
}
return current->Enable( enable );
}
bool wxRadioBox::IsItemEnabled(unsigned int item) const
{
if (!IsValid( item ))
return false;
unsigned int i = 0;
wxRadioButton *current = m_radioButtonCycle;
while (i != item)
{
i++;
current = current->NextInCycle();
}
return current->IsEnabled();
}
// Returns the radiobox label
//
wxString wxRadioBox::GetLabel() const
{
return wxControl::GetLabel();
}
// Returns the label for the given button
//
wxString wxRadioBox::GetString(unsigned int item) const
{
wxRadioButton *current;
if (!IsValid( item ))
return wxEmptyString;
unsigned int i = 0;
current = m_radioButtonCycle;
while (i != item)
{
i++;
current = current->NextInCycle();
}
return current->GetLabel();
}
// Returns the zero-based position of the selected button
//
int wxRadioBox::GetSelection() const
{
int i;
wxRadioButton *current;
i = 0;
current = m_radioButtonCycle;
while (!current->GetValue())
{
i++;
current = current->NextInCycle();
}
return i;
}
// Sets the radiobox label
//
void wxRadioBox::SetLabel(const wxString& label)
{
return wxControl::SetLabel( label );
}
// Sets the label of a given button
//
void wxRadioBox::SetString(unsigned int item,const wxString& label)
{
if (!IsValid( item ))
return;
unsigned int i = 0;
wxRadioButton *current = m_radioButtonCycle;
while (i != item)
{
i++;
current = current->NextInCycle();
}
return current->SetLabel( label );
}
// Sets a button by passing the desired position. This does not cause
// wxEVT_COMMAND_RADIOBOX_SELECTED event to get emitted
//
void wxRadioBox::SetSelection(int item)
{
int i;
wxRadioButton *current;
if (!IsValid( item ))
return;
i = 0;
current = m_radioButtonCycle;
while (i != item)
{
i++;
current = current->NextInCycle();
}
current->SetValue( true );
}
// Shows or hides the entire radiobox
//
bool wxRadioBox::Show(bool show)
{
wxRadioButton *current;
current = m_radioButtonCycle;
for (unsigned int i=0; i<m_noItems; i++)
{
current->Show( show );
current = current->NextInCycle();
}
wxControl::Show( show );
return true;
}
// Shows or hides the given button
//
bool wxRadioBox::Show(unsigned int item, bool show)
{
if (!IsValid( item ))
return false;
unsigned int i = 0;
wxRadioButton *current = m_radioButtonCycle;
while (i != item)
{
i++;
current = current->NextInCycle();
}
return current->Show( show );
}
bool wxRadioBox::IsItemShown(unsigned int item) const
{
if (!IsValid( item ))
return false;
unsigned int i = 0;
wxRadioButton *current = m_radioButtonCycle;
while (i != item)
{
i++;
current = current->NextInCycle();
}
return current->IsShown();
}
// Simulates the effect of the user issuing a command to the item
//
void wxRadioBox::Command( wxCommandEvent& event )
{
SetSelection( event.GetInt() );
ProcessCommand( event );
}
// Sets the selected button to receive keyboard input
//
void wxRadioBox::SetFocus()
{
wxRadioButton *current;
current = m_radioButtonCycle;
while (!current->GetValue())
{
current = current->NextInCycle();
}
current->SetFocus();
}
// Simulates the effect of the user issuing a command to the item
//
#if wxOSX_USE_CARBON
#define RADIO_SIZE 20
#else
// Cocoa has an additional border are of about 3 pixels
#define RADIO_SIZE 23
#endif
void wxRadioBox::DoSetSize(int x, int y, int width, int height, int sizeFlags)
{
int i;
wxRadioButton *current;
// define the position
int x_current, y_current;
int x_offset, y_offset;
int widthOld, heightOld;
GetSize( &widthOld, &heightOld );
GetPosition( &x_current, &y_current );
x_offset = x;
y_offset = y;
if (!(sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
{
if (x == wxDefaultCoord)
x_offset = x_current;
if (y == wxDefaultCoord)
y_offset = y_current;
}
// define size
int charWidth, charHeight;
int maxWidth, maxHeight;
int eachWidth[128], eachHeight[128];
int totWidth, totHeight;
GetTextExtent(
wxT("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"),
&charWidth, &charHeight );
charWidth /= 52;
maxWidth = -1;
maxHeight = -1;
wxSize bestSizeRadio ;
if ( m_radioButtonCycle )
bestSizeRadio = m_radioButtonCycle->GetBestSize();
for (unsigned int i = 0 ; i < m_noItems; i++)
{
GetTextExtent(GetString(i), &eachWidth[i], &eachHeight[i] );
eachWidth[i] = eachWidth[i] + RADIO_SIZE;
eachHeight[i] = wxMax( eachHeight[i], bestSizeRadio.y );
if (maxWidth < eachWidth[i])
maxWidth = eachWidth[i];
if (maxHeight < eachHeight[i])
maxHeight = eachHeight[i];
}
// according to HIG (official space - 3 Pixels Diff between Frame and Layout size)
int space = 3;
if ( GetWindowVariant() == wxWINDOW_VARIANT_MINI )
space = 2;
totHeight = GetRowCount() * maxHeight + (GetRowCount() - 1) * space;
totWidth = GetColumnCount() * (maxWidth + charWidth);
wxSize sz = DoGetSizeFromClientSize( wxSize( totWidth, totHeight ) ) ;
// change the width / height only when specified
if ( width == wxDefaultCoord )
{
if ( sizeFlags & wxSIZE_AUTO_WIDTH )
width = sz.x;
else
width = widthOld;
}
if ( height == wxDefaultCoord )
{
if ( sizeFlags & wxSIZE_AUTO_HEIGHT )
height = sz.y;
else
height = heightOld;
}
wxControl::DoSetSize( x_offset, y_offset, width, height, wxSIZE_AUTO );
// arrange radio buttons
int x_start, y_start;
x_start = ( width - sz.x ) / 2;
y_start = ( height - sz.y ) / 2;
x_offset = x_start;
y_offset = y_start;
current = m_radioButtonCycle;
for (i = 0 ; i < (int)m_noItems; i++)
{
// not to do for the zero button!
if ((i > 0) && ((i % GetMajorDim()) == 0))
{
if (m_windowStyle & wxRA_SPECIFY_ROWS)
{
x_offset += maxWidth + charWidth;
y_offset = y_start;
}
else
{
x_offset = x_start;
y_offset += maxHeight + space;
}
}
current->SetSize( x_offset, y_offset, eachWidth[i], eachHeight[i] );
current = current->NextInCycle();
if (m_windowStyle & wxRA_SPECIFY_ROWS)
y_offset += maxHeight + space;
else
x_offset += maxWidth + charWidth;
}
}
wxSize wxRadioBox::DoGetBestSize() const
{
int charWidth, charHeight;
int maxWidth, maxHeight;
int eachWidth, eachHeight;
int totWidth, totHeight;
wxFont font = GetFont(); // GetParent()->GetFont()
GetTextExtent(
wxT("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"),
&charWidth, &charHeight, NULL, NULL, &font );
charWidth /= 52;
maxWidth = -1;
maxHeight = -1;
wxSize bestSizeRadio ;
if ( m_radioButtonCycle )
bestSizeRadio = m_radioButtonCycle->GetBestSize();
for (unsigned int i = 0 ; i < m_noItems; i++)
{
GetTextExtent(GetString(i), &eachWidth, &eachHeight, NULL, NULL, &font );
eachWidth = (eachWidth + RADIO_SIZE);
eachHeight = wxMax(eachHeight, bestSizeRadio.y );
if (maxWidth < eachWidth)
maxWidth = eachWidth;
if (maxHeight < eachHeight)
maxHeight = eachHeight;
}
// according to HIG (official space - 3 Pixels Diff between Frame and Layout size)
int space = 3;
if ( GetWindowVariant() == wxWINDOW_VARIANT_MINI )
space = 2;
totHeight = GetRowCount() * maxHeight + (GetRowCount() - 1) * space;
totWidth = GetColumnCount() * (maxWidth + charWidth);
wxSize sz = DoGetSizeFromClientSize( wxSize( totWidth, totHeight ) );
totWidth = sz.x;
totHeight = sz.y;
// optimum size is an additional 5 pt border to all sides
totWidth += 10;
totHeight += 10;
// handle radio box title as well
GetTextExtent( GetLabel(), &eachWidth, NULL );
eachWidth = (int)(eachWidth + RADIO_SIZE) + 3 * charWidth;
if (totWidth < eachWidth)
totWidth = eachWidth;
return wxSize( totWidth, totHeight );
}
bool wxRadioBox::SetFont(const wxFont& font)
{
bool retval = wxWindowBase::SetFont( font );
// dont' update the native control, it has its own small font
// should we iterate over the children ?
return retval;
}
#endif // wxUSE_RADIOBOX