// Created: 03.06.01
// RCS-ID: $Id$
// Copyright: (c) 2001 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
-// License: wxWindows licence
+// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
// ============================================================================
#include "wx/radiobox.h"
#endif //WX_PRECOMP
+#if wxUSE_TOOLTIPS
+ #include "wx/tooltip.h"
+#endif // wxUSE_TOOLTIPS
+
+#if wxUSE_HELP
+ #include "wx/cshelp.h"
+#endif
+
// ============================================================================
// implementation
// ============================================================================
+void wxRadioBoxBase::SetMajorDim(unsigned int majorDim, long style)
+{
+ wxCHECK_RET( majorDim != 0, wxT("major radiobox dimension can't be 0") );
+
+ m_majorDim = majorDim;
+
+ int minorDim = (GetCount() + m_majorDim - 1) / m_majorDim;
+
+ if ( style & wxRA_SPECIFY_COLS )
+ {
+ m_numCols = majorDim;
+ m_numRows = minorDim;
+ }
+ else // wxRA_SPECIFY_ROWS
+ {
+ m_numCols = minorDim;
+ m_numRows = majorDim;
+ }
+}
+
int wxRadioBoxBase::GetNextItem(int item, wxDirection dir, long style) const
{
+ const int itemStart = item;
+
int count = GetCount(),
numCols = GetColumnCount(),
numRows = GetRowCount();
bool horz = (style & wxRA_SPECIFY_COLS) != 0;
- switch ( dir )
+ do
{
- case wxUP:
- if ( horz )
- {
- item -= numCols;
- }
- else // vertical layout
- {
- if ( !item-- )
- item = count - 1;
- }
- break;
+ switch ( dir )
+ {
+ case wxUP:
+ if ( horz )
+ {
+ item -= numCols;
+ }
+ else // vertical layout
+ {
+ if ( !item-- )
+ item = count - 1;
+ }
+ break;
- case wxLEFT:
- if ( horz )
- {
- if ( !item-- )
- item = count - 1;
- }
- else // vertical layout
- {
- item -= numRows;
- }
- break;
+ case wxLEFT:
+ if ( horz )
+ {
+ if ( !item-- )
+ item = count - 1;
+ }
+ else // vertical layout
+ {
+ item -= numRows;
+ }
+ break;
- case wxDOWN:
- if ( horz )
- {
- item += numCols;
- }
- else // vertical layout
- {
- if ( ++item == count )
- item = 0;
- }
- break;
+ case wxDOWN:
+ if ( horz )
+ {
+ item += numCols;
+ }
+ else // vertical layout
+ {
+ if ( ++item == count )
+ item = 0;
+ }
+ break;
- case wxRIGHT:
- if ( horz )
- {
- if ( ++item == count )
- item = 0;
- }
- else // vertical layout
- {
- item += numRows;
- }
- break;
+ case wxRIGHT:
+ if ( horz )
+ {
+ if ( ++item == count )
+ item = 0;
+ }
+ else // vertical layout
+ {
+ item += numRows;
+ }
+ break;
- default:
- wxFAIL_MSG( _T("unexpected wxDirection value") );
- return wxNOT_FOUND;
+ default:
+ wxFAIL_MSG( wxT("unexpected wxDirection value") );
+ return wxNOT_FOUND;
+ }
+
+ // ensure that the item is in range [0..count)
+ if ( item < 0 )
+ {
+ // first map the item to the one in the same column but in the last
+ // row
+ item += count;
+
+ // now there are 2 cases: either it is the first item of the last
+ // row in which case we need to wrap again and get to the last item
+ // or we can just go to the previous item
+ if ( item % (horz ? numCols : numRows) )
+ item--;
+ else
+ item = count - 1;
+ }
+ else if ( item >= count )
+ {
+ // same logic as above
+ item -= count;
+
+ // ... except that we need to check if this is not the last item,
+ // not the first one
+ if ( (item + 1) % (horz ? numCols : numRows) )
+ item++;
+ else
+ item = 0;
+ }
+
+ wxASSERT_MSG( item < count && item >= 0,
+ wxT("logic error in wxRadioBox::GetNextItem()") );
+ }
+ // we shouldn't select the non-active items, continue looking for a
+ // visible and shown one unless we came back to the item we started from in
+ // which case bail out to avoid infinite loop
+ while ( !(IsItemShown(item) && IsItemEnabled(item)) && item != itemStart );
+
+ return item;
+}
+
+#if wxUSE_TOOLTIPS
+
+void wxRadioBoxBase::SetItemToolTip(unsigned int item, const wxString& text)
+{
+ wxASSERT_MSG( item < GetCount(), wxT("Invalid item index") );
+
+ // extend the array to have entries for all our items on first use
+ if ( !m_itemsTooltips )
+ {
+ m_itemsTooltips = new wxToolTipArray;
+ m_itemsTooltips->resize(GetCount());
}
- // ensure that the item is in range [0..count)
- if ( item < 0 )
+ wxToolTip *tooltip = (*m_itemsTooltips)[item];
+
+ bool changed = true;
+ if ( text.empty() )
{
- // first map the item to the one in the same column but in the last row
- item += count;
-
- // now there are 2 cases: either it is the first item of the last row
- // in which case we need to wrap again and get to the last item or we
- // can just go to the previous item
- if ( item % (horz ? numCols : numRows) )
- item--;
- else
- item = count - 1;
+ if ( tooltip )
+ {
+ // delete the tooltip
+ wxDELETE(tooltip);
+ }
+ else // nothing to do
+ {
+ changed = false;
+ }
}
- else if ( item >= count )
+ else // non empty tooltip text
{
- // same logic as above
- item -= count;
-
- // ... except that we need to check if this is not the last item, not
- // the first one
- if ( (item + 1) % (horz ? numCols : numRows) )
- item++;
- else
- item = 0;
+ if ( tooltip )
+ {
+ // just change the existing tooltip text, don't change the tooltip
+ tooltip->SetTip(text);
+ changed = false;
+ }
+ else // no tooltip yet
+ {
+ // create the new one
+ tooltip = new wxToolTip(text);
+ }
}
- wxASSERT_MSG( item < count && item >= 0,
- _T("logic error in wxRadioBox::GetNextItem()") );
-
- return item;
+ if ( changed )
+ {
+ (*m_itemsTooltips)[item] = tooltip;
+ DoSetItemToolTip(item, tooltip);
+ }
}
-#if WXWIN_COMPATIBILITY_2_4
-
-// these functions are deprecated and don't do anything
-int wxRadioBoxBase::GetNumberOfRowsOrCols() const
+void
+wxRadioBoxBase::DoSetItemToolTip(unsigned int WXUNUSED(item),
+ wxToolTip * WXUNUSED(tooltip))
{
- return 1;
+ // per-item tooltips not implemented by default
}
-void wxRadioBoxBase::SetNumberOfRowsOrCols(int WXUNUSED(n))
+#endif // wxUSE_TOOLTIPS
+
+wxRadioBoxBase::~wxRadioBoxBase()
{
-}
+#if wxUSE_TOOLTIPS
+ if ( m_itemsTooltips )
+ {
+ const size_t n = m_itemsTooltips->size();
+ for ( size_t i = 0; i < n; i++ )
+ delete (*m_itemsTooltips)[i];
-#endif // WXWIN_COMPATIBILITY_2_4
+ delete m_itemsTooltips;
+ }
+#endif // wxUSE_TOOLTIPS
+}
-#if WXWIN_COMPATIBILITY_2_2
+#if wxUSE_HELP
-int wxRadioBoxBase::Number() const
+// set helptext for a particular item
+void wxRadioBoxBase::SetItemHelpText(unsigned int n, const wxString& helpText)
{
- return GetCount();
+ wxCHECK_RET( n < GetCount(), wxT("Invalid item index") );
+
+ if ( m_itemsHelpTexts.empty() )
+ {
+ // once-only initialization of the array: reserve space for all items
+ m_itemsHelpTexts.Add(wxEmptyString, GetCount());
+ }
+
+ m_itemsHelpTexts[n] = helpText;
}
-wxString wxRadioBoxBase::GetLabel(int n) const
+// retrieve helptext for a particular item
+wxString wxRadioBoxBase::GetItemHelpText( unsigned int n ) const
{
- return GetString(n);
+ wxCHECK_MSG( n < GetCount(), wxEmptyString, wxT("Invalid item index") );
+
+ return m_itemsHelpTexts.empty() ? wxString() : m_itemsHelpTexts[n];
}
-void wxRadioBoxBase::SetLabel(int n, const wxString& label)
+// return help text for the item for which wxEVT_HELP was generated.
+wxString wxRadioBoxBase::DoGetHelpTextAtPoint(const wxWindow *derived,
+ const wxPoint& pt,
+ wxHelpEvent::Origin origin) const
{
- SetString(n, label);
+ int item;
+ switch ( origin )
+ {
+ case wxHelpEvent::Origin_HelpButton:
+ item = GetItemFromPoint(pt);
+ break;
+
+ case wxHelpEvent::Origin_Keyboard:
+ item = GetSelection();
+ break;
+
+ default:
+ wxFAIL_MSG( "unknown help even origin" );
+ // fall through
+
+ case wxHelpEvent::Origin_Unknown:
+ // this value is used when we're called from GetHelpText() for the
+ // radio box itself, so don't return item-specific text in this case
+ item = wxNOT_FOUND;
+ }
+
+ if ( item != wxNOT_FOUND )
+ {
+ wxString text = GetItemHelpText(static_cast<unsigned int>(item));
+ if( !text.empty() )
+ return text;
+ }
+
+ return derived->wxWindowBase::GetHelpTextAtPoint(pt, origin);
}
-#endif // WXWIN_COMPATIBILITY_2_2
+#endif // wxUSE_HELP
#endif // wxUSE_RADIOBOX