1 ///////////////////////////////////////////////////////////////////////////////
2 // Name:        src/common/radiocmn.cpp
3 // Purpose:     wxRadioBox methods common to all ports
4 // Author:      Vadim Zeitlin
5 // Modified by:
6 // Created:     03.06.01
7 // RCS-ID:      $Id: radiocmn.cpp 54930 2008-08-02 19:45:23Z VZ $
8 // Copyright:   (c) 2001 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // License:     wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11 
12 // ============================================================================
13 // declarations
14 // ============================================================================
15 
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19 
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22 
23 #ifdef __BORLANDC__
24     #pragma hdrstop
25 #endif
26 
27 #if wxUSE_RADIOBOX
28 
29 #ifndef WX_PRECOMP
30     #include "wx/radiobox.h"
31 #endif //WX_PRECOMP
32 
33 #if wxUSE_TOOLTIPS
34     #include "wx/tooltip.h"
35 #endif // wxUSE_TOOLTIPS
36 
37 #if wxUSE_HELP
38     #include "wx/cshelp.h"
39 #endif
40 
41 // ============================================================================
42 // implementation
43 // ============================================================================
44 
SetMajorDim(unsigned int majorDim,long style)45 void wxRadioBoxBase::SetMajorDim(unsigned int majorDim, long style)
46 {
47     wxCHECK_RET( majorDim != 0, _T("major radiobox dimension can't be 0") );
48 
49     m_majorDim = majorDim;
50 
51     int minorDim = (GetCount() + m_majorDim - 1) / m_majorDim;
52 
53     if ( style & wxRA_SPECIFY_COLS )
54     {
55         m_numCols = majorDim;
56         m_numRows = minorDim;
57     }
58     else // wxRA_SPECIFY_ROWS
59     {
60         m_numCols = minorDim;
61         m_numRows = majorDim;
62     }
63 }
64 
GetNextItem(int item,wxDirection dir,long style) const65 int wxRadioBoxBase::GetNextItem(int item, wxDirection dir, long style) const
66 {
67     const int itemStart = item;
68 
69     int count = GetCount(),
70         numCols = GetColumnCount(),
71         numRows = GetRowCount();
72 
73     bool horz = (style & wxRA_SPECIFY_COLS) != 0;
74 
75     do
76     {
77         switch ( dir )
78         {
79             case wxUP:
80                 if ( horz )
81                 {
82                     item -= numCols;
83                 }
84                 else // vertical layout
85                 {
86                     if ( !item-- )
87                         item = count - 1;
88                 }
89                 break;
90 
91             case wxLEFT:
92                 if ( horz )
93                 {
94                     if ( !item-- )
95                         item = count - 1;
96                 }
97                 else // vertical layout
98                 {
99                     item -= numRows;
100                 }
101                 break;
102 
103             case wxDOWN:
104                 if ( horz )
105                 {
106                     item += numCols;
107                 }
108                 else // vertical layout
109                 {
110                     if ( ++item == count )
111                         item = 0;
112                 }
113                 break;
114 
115             case wxRIGHT:
116                 if ( horz )
117                 {
118                     if ( ++item == count )
119                         item = 0;
120                 }
121                 else // vertical layout
122                 {
123                     item += numRows;
124                 }
125                 break;
126 
127             default:
128                 wxFAIL_MSG( _T("unexpected wxDirection value") );
129                 return wxNOT_FOUND;
130         }
131 
132         // ensure that the item is in range [0..count)
133         if ( item < 0 )
134         {
135             // first map the item to the one in the same column but in the last
136             // row
137             item += count;
138 
139             // now there are 2 cases: either it is the first item of the last
140             // row in which case we need to wrap again and get to the last item
141             // or we can just go to the previous item
142             if ( item % (horz ? numCols : numRows) )
143                 item--;
144             else
145                 item = count - 1;
146         }
147         else if ( item >= count )
148         {
149             // same logic as above
150             item -= count;
151 
152             // ... except that we need to check if this is not the last item,
153             // not the first one
154             if ( (item + 1) % (horz ? numCols : numRows) )
155                 item++;
156             else
157                 item = 0;
158         }
159 
160         wxASSERT_MSG( item < count && item >= 0,
161                       _T("logic error in wxRadioBox::GetNextItem()") );
162     }
163     // we shouldn't select the non-active items, continue looking for a
164     // visible and shown one unless we came back to the item we started from in
165     // which case bail out to avoid infinite loop
166     while ( !(IsItemShown(item) && IsItemEnabled(item)) && item != itemStart );
167 
168     return item;
169 }
170 
171 #if wxUSE_TOOLTIPS
172 
SetItemToolTip(unsigned int item,const wxString & text)173 void wxRadioBoxBase::SetItemToolTip(unsigned int item, const wxString& text)
174 {
175     wxASSERT_MSG( item < GetCount(), _T("Invalid item index") );
176 
177     // extend the array to have entries for all our items on first use
178     if ( !m_itemsTooltips )
179     {
180         m_itemsTooltips = new wxToolTipArray;
181         m_itemsTooltips->resize(GetCount());
182     }
183 
184     wxToolTip *tooltip = (*m_itemsTooltips)[item];
185 
186     bool changed = true;
187     if ( text.empty() )
188     {
189         if ( tooltip )
190         {
191             // delete the tooltip
192             delete tooltip;
193             tooltip = NULL;
194         }
195         else // nothing to do
196         {
197             changed = false;
198         }
199     }
200     else // non empty tooltip text
201     {
202         if ( tooltip )
203         {
204             // just change the existing tooltip text, don't change the tooltip
205             tooltip->SetTip(text);
206             changed = false;
207         }
208         else // no tooltip yet
209         {
210             // create the new one
211             tooltip = new wxToolTip(text);
212         }
213     }
214 
215     if ( changed )
216     {
217         (*m_itemsTooltips)[item] = tooltip;
218         DoSetItemToolTip(item, tooltip);
219     }
220 }
221 
222 void
DoSetItemToolTip(unsigned int WXUNUSED (item),wxToolTip * WXUNUSED (tooltip))223 wxRadioBoxBase::DoSetItemToolTip(unsigned int WXUNUSED(item),
224                                  wxToolTip * WXUNUSED(tooltip))
225 {
226     // per-item tooltips not implemented by default
227 }
228 
229 #endif // wxUSE_TOOLTIPS
230 
~wxRadioBoxBase()231 wxRadioBoxBase::~wxRadioBoxBase()
232 {
233 #if wxUSE_TOOLTIPS
234     if ( m_itemsTooltips )
235     {
236         const size_t n = m_itemsTooltips->size();
237         for ( size_t i = 0; i < n; i++ )
238             delete (*m_itemsTooltips)[i];
239 
240         delete m_itemsTooltips;
241     }
242 #endif // wxUSE_TOOLTIPS
243 }
244 
245 #if wxUSE_HELP
246 
247 // set helptext for a particular item
SetItemHelpText(unsigned int n,const wxString & helpText)248 void wxRadioBoxBase::SetItemHelpText(unsigned int n, const wxString& helpText)
249 {
250     wxCHECK_RET( n < GetCount(), _T("Invalid item index") );
251 
252     if ( m_itemsHelpTexts.empty() )
253     {
254         // once-only initialization of the array: reserve space for all items
255         m_itemsHelpTexts.Add(wxEmptyString, GetCount());
256     }
257 
258     m_itemsHelpTexts[n] = helpText;
259 }
260 
261 // retrieve helptext for a particular item
GetItemHelpText(unsigned int n) const262 wxString wxRadioBoxBase::GetItemHelpText( unsigned int n ) const
263 {
264     wxCHECK_MSG( n < GetCount(), wxEmptyString, _T("Invalid item index") );
265 
266     return m_itemsHelpTexts.empty() ? wxString() : m_itemsHelpTexts[n];
267 }
268 
269 // return help text for the item for which wxEVT_HELP was generated.
DoGetHelpTextAtPoint(const wxWindow * derived,const wxPoint & pt,wxHelpEvent::Origin origin) const270 wxString wxRadioBoxBase::DoGetHelpTextAtPoint(const wxWindow *derived,
271                                               const wxPoint& pt,
272                                               wxHelpEvent::Origin origin) const
273 {
274     const int item = origin == wxHelpEvent::Origin_HelpButton
275                         ? GetItemFromPoint(pt)
276                         : GetSelection();
277 
278     if ( item != wxNOT_FOUND )
279     {
280         wxString text = GetItemHelpText(wx_static_cast(unsigned int, item));
281         if( !text.empty() )
282             return text;
283     }
284 
285     return derived->wxWindowBase::GetHelpTextAtPoint(pt, origin);
286 }
287 
288 #endif // wxUSE_HELP
289 
290 #if WXWIN_COMPATIBILITY_2_4
291 
292 // these functions are deprecated and don't do anything
GetNumberOfRowsOrCols() const293 int wxRadioBoxBase::GetNumberOfRowsOrCols() const
294 {
295     return 1;
296 }
297 
SetNumberOfRowsOrCols(int WXUNUSED (n))298 void wxRadioBoxBase::SetNumberOfRowsOrCols(int WXUNUSED(n))
299 {
300 }
301 
302 #endif // WXWIN_COMPATIBILITY_2_4
303 
304 #endif // wxUSE_RADIOBOX
305