wxRadioBox starts to work

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/wxUNIVERSAL@8332 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2000-09-11 20:21:57 +00:00
parent 6e78473c26
commit 35fd96a83a
10 changed files with 585 additions and 5 deletions

2
TODO
View File

@@ -5,3 +5,5 @@ All
MSW MSW
GTK GTK
* check/radio box remains pressed

View File

@@ -68,6 +68,19 @@
# endif # endif
#endif /* wxUSE_RADIOBTN */ #endif /* wxUSE_RADIOBTN */
#if wxUSE_RADIOBOX
# if !wxUSE_RADIOBTN || !wxUSE_STATBOX
# ifdef wxABORT_ON_CONFIG_ERROR
# error "wxUSE_RADIOBOX requires wxUSE_RADIOBTN and wxUSE_STATBOX"
# else
# undef wxUSE_RADIOBTN
# undef wxUSE_STATBOX
# define wxUSE_RADIOBTN 1
# define wxUSE_STATBOX 1
# endif
# endif
#endif /* wxUSE_RADIOBOX */
#if wxUSE_STOPWATCH #if wxUSE_STOPWATCH
# if !wxUSE_LONGLONG # if !wxUSE_LONGLONG
# ifdef wxABORT_ON_CONFIG_ERROR # ifdef wxABORT_ON_CONFIG_ERROR

View File

@@ -18,7 +18,72 @@
WXDLLEXPORT_DATA(extern const wxChar*) wxRadioBoxNameStr; WXDLLEXPORT_DATA(extern const wxChar*) wxRadioBoxNameStr;
#if defined(__WXMSW__) // ----------------------------------------------------------------------------
// wxRadioBoxBase is not a base class at all, but rather a mix-in because the
// real wxRadioBox derives from different classes on different platforms: for
// example, it is a
// ----------------------------------------------------------------------------
class WXDLLEXPORT wxRadioBoxBase
{
public:
// selection
virtual void SetSelection(int n) = 0;
virtual int GetSelection() const = 0;
virtual wxString GetStringSelection() const
{
wxString s;
int sel = GetSelection();
if ( sel != wxNOT_FOUND )
s = GetString(sel);
return s;
}
virtual bool SetStringSelection(const wxString& s)
{
int sel = FindString(s);
if ( sel != wxNOT_FOUND )
{
SetSelection(sel);
return TRUE;
}
return FALSE;
}
// string access
virtual int GetCount() const = 0;
virtual int FindString(const wxString& s) const
{
int count = GetCount();
for ( int n = 0; n < count; n++ )
{
if ( GetString(n) == s )
return n;
}
return wxNOT_FOUND;
}
virtual wxString GetString(int n) const = 0;
virtual void SetString(int n, const wxString& label) = 0;
// change the individual radio button state
virtual void Enable(int n, bool enable = TRUE) = 0;
virtual void Show(int n, bool show = TRUE) = 0;
// for compatibility only, don't use
int Number() const { return GetCount(); }
wxString GetLabel(int n) const { return GetString(n); }
void SetLabel(int n, const wxString& label) { SetString(n, label); }
};
#if defined(__WXUNIVERSAL__)
#include "wx/univ/radiobox.h"
#elif defined(__WXMSW__)
#include "wx/msw/radiobox.h" #include "wx/msw/radiobox.h"
#elif defined(__WXMOTIF__) #elif defined(__WXMOTIF__)
#include "wx/motif/radiobox.h" #include "wx/motif/radiobox.h"

122
include/wx/univ/radiobox.h Normal file
View File

@@ -0,0 +1,122 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/univ/radiobox.h
// Purpose: wxRadioBox declaration
// Author: Vadim Zeitlin
// Modified by:
// Created: 11.09.00
// RCS-ID: $Id$
// Copyright: (c) 2000 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
// Licence: wxWindows license
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_UNIV_RADIOBOX_H_
#define _WX_UNIV_RADIOBOX_H_
#ifdef __GNUG__
#pragma interface "univradiobox.h"
#endif
class WXDLLEXPORT wxRadioButton;
#include "wx/statbox.h"
#include "wx/dynarray.h"
WX_DEFINE_ARRAY(wxRadioButton *, wxArrayRadioButtons);
// ----------------------------------------------------------------------------
// wxRadioBox: a box full of radio buttons
// ----------------------------------------------------------------------------
class WXDLLEXPORT wxRadioBox : public wxStaticBox,
public wxRadioBoxBase
{
public:
// wxRadioBox construction
wxRadioBox() { Init(); }
wxRadioBox(wxWindow *parent,
wxWindowID id,
const wxString& title,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
int n = 0, const wxString *choices = NULL,
int majorDim = 0,
long style = wxRA_SPECIFY_COLS,
const wxValidator& val = wxDefaultValidator,
const wxString& name = wxRadioBoxNameStr)
{
Init();
(void)Create(parent, id, title, pos, size, n, choices,
majorDim, style, val, name);
}
bool Create(wxWindow *parent,
wxWindowID id,
const wxString& title,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
int n = 0, const wxString *choices = NULL,
int majorDim = 0,
long style = wxRA_SPECIFY_COLS,
const wxValidator& val = wxDefaultValidator,
const wxString& name = wxRadioBoxNameStr);
// implement wxRadioBox interface
virtual void SetSelection(int n);
virtual int GetSelection() const;
virtual int GetCount() const { return m_buttons.GetCount(); }
virtual wxString GetString(int n) const;
virtual void SetString(int n, const wxString& label);
virtual void Enable(int n, bool enable = TRUE);
virtual void Show(int n, bool show = TRUE);
// we also override the wxControl methods to avoid virtual function hiding
virtual bool Enable(bool enable = TRUE);
virtual bool Show(bool show = TRUE);
virtual wxString GetLabel() const;
virtual void SetLabel(const wxString& label);
// wxUniversal-only methods
void Append(int n, const wxString *choices);
protected:
// override the base class methods dealing with window positioning/sizing
// as we must move/size the buttons as well
virtual void DoMoveWindow(int x, int y, int width, int height);
virtual wxSize DoGetBestClientSize() const;
// common part of all ctors
void Init();
// check that the index is valid
bool IsValid(int n) const { return n >= 0 && n < GetCount(); }
// sets m_majorDim and calculate m_numCols and m_numRows
void SetMajorDim(int majorDim);
// calculate the max size of all buttons
wxSize GetMaxButtonSize() const;
// the currently selected radio button or -1
int m_selection;
// the parameters defining the button layout: majorDim meaning depends on
// the style and is the (max) number of columns if it includes
// wxRA_SPECIFY_COLS and is the (max) number of rows if it includes
// wxRA_SPECIFY_ROWS - the number of rows and columns is calculated from
// it
int m_majorDim,
m_numCols,
m_numRows;
// all radio buttons
wxArrayRadioButtons m_buttons;
private:
DECLARE_DYNAMIC_CLASS(wxRadioBox)
};
#endif // _WX_UNIV_RADIOBOX_H_

View File

@@ -35,7 +35,7 @@ public:
const wxSize& size = wxDefaultSize, const wxSize& size = wxDefaultSize,
long style = 0, long style = 0,
const wxValidator& validator = wxDefaultValidator, const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxCheckBoxNameStr) const wxString& name = wxRadioButtonNameStr)
{ {
Init(); Init();
@@ -49,7 +49,7 @@ public:
const wxSize& size = wxDefaultSize, const wxSize& size = wxDefaultSize,
long style = 0, long style = 0,
const wxValidator& validator = wxDefaultValidator, const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxCheckBoxNameStr); const wxString& name = wxRadioButtonNameStr);
// override some base class methods // override some base class methods
virtual void ChangeValue(bool value); virtual void ChangeValue(bool value);

View File

@@ -1,4 +1,4 @@
/////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// Name: wx/univ/statbox.h // Name: wx/univ/statbox.h
// Purpose: wxStaticBox declaration // Purpose: wxStaticBox declaration
// Author: Vadim Zeitlin // Author: Vadim Zeitlin
@@ -47,9 +47,21 @@ public:
long style = 0, long style = 0,
const wxString& name = wxStaticBoxNameStr); const wxString& name = wxStaticBoxNameStr);
// the origin of the static box is inside the border and under the label:
// take account of this
virtual wxPoint GetClientAreaOrigin() const;
protected: protected:
// take into account the border/label here as well
virtual void DoSetClientSize(int width, int height);
virtual void DoGetClientSize(int *width, int *height) const;
// draw the control
virtual void DoDraw(wxControlRenderer *renderer); virtual void DoDraw(wxControlRenderer *renderer);
// get the size of the border
wxRect GetBorderGeometry() const;
private: private:
DECLARE_DYNAMIC_CLASS(wxStaticBox) DECLARE_DYNAMIC_CLASS(wxStaticBox)
}; };

View File

@@ -38,6 +38,7 @@
#include "wx/button.h" #include "wx/button.h"
#include "wx/checkbox.h" #include "wx/checkbox.h"
#include "wx/listbox.h" #include "wx/listbox.h"
#include "wx/radiobox.h"
#include "wx/radiobut.h" #include "wx/radiobut.h"
#include "wx/scrolbar.h" #include "wx/scrolbar.h"
#include "wx/scrolwin.h" #include "wx/scrolwin.h"
@@ -345,6 +346,17 @@ MyUnivFrame::MyUnivFrame(const wxString& title)
wxALIGN_RIGHT); wxALIGN_RIGHT);
new wxRadioButton(this, -1, _T("Toggle me"), wxPoint(10, 600)); new wxRadioButton(this, -1, _T("Toggle me"), wxPoint(10, 600));
new wxRadioButton(this, -1, _T("And then me"), wxPoint(150, 600)); new wxRadioButton(this, -1, _T("And then me"), wxPoint(150, 600));
new wxRadioBox(this, -1, _T("&Horizontal"),
wxPoint(100, 470), wxDefaultSize,
WXSIZEOF(choices), choices,
WXSIZEOF(choices),
wxRA_SPECIFY_COLS);
new wxRadioBox(this, -1, _T("&Vertical"),
wxPoint(300, 550), wxDefaultSize,
WXSIZEOF(choices), choices,
WXSIZEOF(choices),
wxRA_SPECIFY_ROWS);
} }
void MyUnivFrame::OnButton(wxCommandEvent& event) void MyUnivFrame::OnButton(wxCommandEvent& event)

View File

@@ -6,6 +6,7 @@ UNIVOBJS = \
control.o \ control.o \
inphand.o \ inphand.o \
listbox.o \ listbox.o \
radiobox.o \
radiobut.o \ radiobut.o \
renderer.o \ renderer.o \
scrolbar.o \ scrolbar.o \
@@ -26,6 +27,7 @@ UNIVDEPS = \
control.d \ control.d \
inphand.d \ inphand.d \
listbox.d \ listbox.d \
radiobox.d \
radiobut.d \ radiobut.d \
renderer.d \ renderer.d \
scrolbar.d \ scrolbar.d \

307
src/univ/radiobox.cpp Normal file
View File

@@ -0,0 +1,307 @@
/////////////////////////////////////////////////////////////////////////////
// Name: univ/radiobox.cpp
// Purpose: wxRadioBox implementation
// Author: Vadim Zeitlin
// Modified by:
// Created: 11.09.00
// RCS-ID: $Id$
// Copyright: (c) 2000 Vadim Zeitlin
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#ifdef __GNUG__
#pragma implementation "univradiobox.h"
#endif
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#if wxUSE_RADIOBOX
#ifndef WX_PRECOMP
#include "wx/dcclient.h"
#include "wx/radiobox.h"
#include "wx/radiobut.h"
#include "wx/validate.h"
#endif
#include "wx/univ/theme.h"
#include "wx/univ/renderer.h"
#include "wx/univ/inphand.h"
#include "wx/univ/colschem.h"
// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------
static const int BUTTON_BORDER_X = 3;
static const int BUTTON_BORDER_Y = 3;
static const int BOX_BORDER_X = 0;
static const int BOX_BORDER_Y = 0;
// ============================================================================
// implementation
// ============================================================================
IMPLEMENT_DYNAMIC_CLASS(wxRadioBox, wxControl)
// ----------------------------------------------------------------------------
// wxRadioBox creation
// ----------------------------------------------------------------------------
void wxRadioBox::Init()
{
m_selection = -1;
m_majorDim = 0;
}
bool wxRadioBox::Create(wxWindow *parent,
wxWindowID id,
const wxString& title,
const wxPoint& pos,
const wxSize& size,
int n,
const wxString *choices,
int majorDim,
long style,
const wxValidator& val,
const wxString& name)
{
if ( !wxStaticBox::Create(parent, id, title, pos, size, style, name) )
return FALSE;
#if wxUSE_VALIDATORS
SetValidator(val);
#endif // wxUSE_VALIDATORS
Append(n, choices);
SetMajorDim(majorDim);
if ( size == wxDefaultSize )
{
SetClientSize(DoGetBestClientSize());
}
return TRUE;
}
void wxRadioBox::SetMajorDim(int majorDim)
{
m_majorDim = majorDim;
int minorDim = (GetCount() + m_majorDim - 1) / m_majorDim;
if ( GetWindowStyle() & wxRA_SPECIFY_COLS )
{
m_numCols = majorDim;
m_numRows = minorDim;
}
else // wxRA_SPECIFY_ROWS
{
m_numCols = minorDim;
m_numRows = majorDim;
}
}
void wxRadioBox::Append(int count, const wxString *choices)
{
if ( !count )
return;
wxWindow *parent = GetParent();
m_buttons.Alloc(count);
for ( int n = 0; n < count; n++ )
{
// make the first button in the box the start of new group
m_buttons.Add(new wxRadioButton(parent, -1, choices[n],
wxDefaultPosition, wxDefaultSize,
n == 0 ? wxRB_GROUP : 0));
}
}
// ----------------------------------------------------------------------------
// selection
// ----------------------------------------------------------------------------
void wxRadioBox::SetSelection(int n)
{
wxCHECK_RET( IsValid(n), _T("invalid index in wxRadioBox::SetSelection") );
// this will unselect the previously selected button in our group
m_buttons[n]->SetValue(TRUE);
}
int wxRadioBox::GetSelection() const
{
return m_selection;
}
// ----------------------------------------------------------------------------
// methods forwarded to the buttons
// ----------------------------------------------------------------------------
wxString wxRadioBox::GetString(int n) const
{
wxCHECK_MSG( IsValid(n), _T(""),
_T("invalid index in wxRadioBox::GetString") );
return m_buttons[n]->GetLabel();
}
void wxRadioBox::SetString(int n, const wxString& label)
{
wxCHECK_RET( IsValid(n), _T("invalid index in wxRadioBox::SetString") );
m_buttons[n]->SetLabel(label);
}
void wxRadioBox::Enable(int n, bool enable)
{
wxCHECK_RET( IsValid(n), _T("invalid index in wxRadioBox::Enable") );
m_buttons[n]->Enable(enable);
}
void wxRadioBox::Show(int n, bool show)
{
wxCHECK_RET( IsValid(n), _T("invalid index in wxRadioBox::Show") );
m_buttons[n]->Show(show);
}
// ----------------------------------------------------------------------------
// methods forwarded to the static box
// ----------------------------------------------------------------------------
bool wxRadioBox::Enable(bool enable)
{
return wxStaticBox::Enable(enable);
}
bool wxRadioBox::Show(bool show)
{
return wxStaticBox::Show(show);
}
wxString wxRadioBox::GetLabel() const
{
return wxStaticBox::GetLabel();
}
void wxRadioBox::SetLabel(const wxString& label)
{
wxStaticBox::SetLabel(label);
}
// ----------------------------------------------------------------------------
// buttons positioning
// ----------------------------------------------------------------------------
wxSize wxRadioBox::GetMaxButtonSize() const
{
int widthMax, heightMax, width, height;
widthMax = heightMax = 0;
int count = GetCount();
for ( int n = 0; n < count; n++ )
{
m_buttons[n]->GetSize(&width, &height);
if ( width > widthMax )
widthMax = width;
if ( height > heightMax )
heightMax = height;
}
// add a intra button border
widthMax += BUTTON_BORDER_X;
heightMax += BUTTON_BORDER_Y;
return wxSize(widthMax, heightMax);
}
/*
Remember that wxRA_SPECIFY_COLS means that the buttons go from top to
bottom and from left to right while wxRA_SPECIFY_ROWS means that they are
laid out from left to right and then from top to bottom
*/
wxSize wxRadioBox::DoGetBestClientSize() const
{
wxSize sizeBtn = GetMaxButtonSize();
sizeBtn.x *= m_numCols;
sizeBtn.y *= m_numRows;
// add a border around all buttons
sizeBtn.x += 2*BOX_BORDER_X;
sizeBtn.y += 2*BOX_BORDER_Y;
return sizeBtn;
}
void wxRadioBox::DoMoveWindow(int x0, int y0, int width, int height)
{
wxStaticBox::DoMoveWindow(x0, y0, width, height);
wxSize sizeBtn = GetMaxButtonSize();
wxPoint ptOrigin = GetClientAreaOrigin();
x0 += ptOrigin.x + BOX_BORDER_X;
y0 += ptOrigin.y + BOX_BORDER_Y;
int x = x0,
y = y0;
int count = GetCount();
for ( int n = 0; n < count; n++ )
{
m_buttons[n]->SetSize(x, y, sizeBtn.x, sizeBtn.y);
if ( GetWindowStyle() & wxRA_SPECIFY_COLS )
{
// from to to bottom
if ( n % m_numRows )
{
// continue in this column
y += sizeBtn.y;
}
else
{
// start a new column
x += sizeBtn.x;
y = y0;
}
}
else // wxRA_SPECIFY_ROWS: mirror the code above
{
// from left to right
if ( n % m_numCols )
{
// continue in this row
x += sizeBtn.x;
}
else
{
// start a new row
y += sizeBtn.y;
x = x0;
}
}
}
}
#endif // wxUSE_RADIOBOX

View File

@@ -65,10 +65,55 @@ bool wxStaticBox::Create(wxWindow *parent,
void wxStaticBox::DoDraw(wxControlRenderer *renderer) void wxStaticBox::DoDraw(wxControlRenderer *renderer)
{ {
// we never have a border, so don't call the base class version whcih draws // we never have a border, so don't call the base class version which draws
// it // it
renderer->DrawFrame(); renderer->DrawFrame();
} }
// ----------------------------------------------------------------------------
// geometry
// ----------------------------------------------------------------------------
wxRect wxStaticBox::GetBorderGeometry() const
{
// FIXME should use the renderer here
wxRect rect;
rect.width =
rect.x = GetCharWidth() / 2 + 1;
rect.y = GetCharHeight() + 1;
rect.height = rect.y / 2;
return rect;
}
wxPoint wxStaticBox::GetClientAreaOrigin() const
{
wxPoint pt = wxControl::GetClientAreaOrigin();
wxRect rect = GetBorderGeometry();
pt.x += rect.x;
pt.y += rect.y;
return pt;
}
void wxStaticBox::DoSetClientSize(int width, int height)
{
wxRect rect = GetBorderGeometry();
wxControl::DoSetClientSize(width + rect.x + rect.width,
height + rect.y + rect.height);
}
void wxStaticBox::DoGetClientSize(int *width, int *height) const
{
wxControl::DoGetClientSize(width, height);
wxRect rect = GetBorderGeometry();
if ( width )
*width -= rect.x + rect.width;
if ( height )
*height -= rect.y + rect.height;
}
#endif // wxUSE_STATBOX #endif // wxUSE_STATBOX