]> git.saurik.com Git - wxWidgets.git/blame - src/common/radiocmn.cpp
Do not allow multiple selection when dragging in the 'value' column
[wxWidgets.git] / src / common / radiocmn.cpp
CommitLineData
e421922f
VZ
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$
8// Copyright: (c) 2001 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
65571936 9// License: wxWindows licence
e421922f
VZ
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
e421922f
VZ
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
c670c855
VZ
33#if wxUSE_TOOLTIPS
34 #include "wx/tooltip.h"
35#endif // wxUSE_TOOLTIPS
36
dc26eeb3
VZ
37#if wxUSE_HELP
38 #include "wx/cshelp.h"
39#endif
40
e421922f
VZ
41// ============================================================================
42// implementation
43// ============================================================================
44
aa61d352 45void wxRadioBoxBase::SetMajorDim(unsigned int majorDim, long style)
21e0a4d5 46{
9a83f860 47 wxCHECK_RET( majorDim != 0, wxT("major radiobox dimension can't be 0") );
21e0a4d5
VZ
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
e421922f
VZ
65int wxRadioBoxBase::GetNextItem(int item, wxDirection dir, long style) const
66{
05d31b3a
VZ
67 const int itemStart = item;
68
e421922f
VZ
69 int count = GetCount(),
70 numCols = GetColumnCount(),
71 numRows = GetRowCount();
72
73 bool horz = (style & wxRA_SPECIFY_COLS) != 0;
74
05d31b3a 75 do
e421922f 76 {
05d31b3a
VZ
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:
9a83f860 128 wxFAIL_MSG( wxT("unexpected wxDirection value") );
05d31b3a
VZ
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,
9a83f860 161 wxT("logic error in wxRadioBox::GetNextItem()") );
e421922f 162 }
05d31b3a
VZ
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 );
e421922f
VZ
167
168 return item;
169}
170
c670c855
VZ
171#if wxUSE_TOOLTIPS
172
173void wxRadioBoxBase::SetItemToolTip(unsigned int item, const wxString& text)
174{
9a83f860 175 wxASSERT_MSG( item < GetCount(), wxT("Invalid item index") );
c670c855
VZ
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
222void
223wxRadioBoxBase::DoSetItemToolTip(unsigned int WXUNUSED(item),
224 wxToolTip * WXUNUSED(tooltip))
225{
226 // per-item tooltips not implemented by default
227}
228
6337cacc
WS
229#endif // wxUSE_TOOLTIPS
230
c670c855
VZ
231wxRadioBoxBase::~wxRadioBoxBase()
232{
6337cacc 233#if wxUSE_TOOLTIPS
c670c855
VZ
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 }
c670c855 242#endif // wxUSE_TOOLTIPS
6337cacc 243}
c670c855 244
dc26eeb3
VZ
245#if wxUSE_HELP
246
247// set helptext for a particular item
248void wxRadioBoxBase::SetItemHelpText(unsigned int n, const wxString& helpText)
249{
9a83f860 250 wxCHECK_RET( n < GetCount(), wxT("Invalid item index") );
dc26eeb3
VZ
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
262wxString wxRadioBoxBase::GetItemHelpText( unsigned int n ) const
263{
9a83f860 264 wxCHECK_MSG( n < GetCount(), wxEmptyString, wxT("Invalid item index") );
dc26eeb3
VZ
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.
270wxString wxRadioBoxBase::DoGetHelpTextAtPoint(const wxWindow *derived,
271 const wxPoint& pt,
272 wxHelpEvent::Origin origin) const
273{
6eb872ea
VZ
274 int item;
275 switch ( origin )
276 {
277 case wxHelpEvent::Origin_HelpButton:
278 item = GetItemFromPoint(pt);
279 break;
280
281 case wxHelpEvent::Origin_Keyboard:
282 item = GetSelection();
283 break;
284
285 default:
286 wxFAIL_MSG( "unknown help even origin" );
287 // fall through
288
289 case wxHelpEvent::Origin_Unknown:
290 // this value is used when we're called from GetHelpText() for the
291 // radio box itself, so don't return item-specific text in this case
292 item = wxNOT_FOUND;
293 }
dc26eeb3
VZ
294
295 if ( item != wxNOT_FOUND )
296 {
5c33522f 297 wxString text = GetItemHelpText(static_cast<unsigned int>(item));
dc26eeb3
VZ
298 if( !text.empty() )
299 return text;
300 }
301
302 return derived->wxWindowBase::GetHelpTextAtPoint(pt, origin);
303}
304
305#endif // wxUSE_HELP
306
e421922f 307#endif // wxUSE_RADIOBOX