]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/os2/spinctrl.cpp
corrected path splitting for mac relative paths
[wxWidgets.git] / src / os2 / spinctrl.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: msw/spinctrl.cpp
3// Purpose: wxSpinCtrl class implementation for Win32
4// Author: David Webster
5// Modified by:
6// Created: 10/15/99
7// RCS-ID: $Id$
8// Copyright: (c) David Webster
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16
17#ifdef __GNUG__
18 #pragma implementation "spinctrlbase.h"
19 #pragma implementation "spinctrl.h"
20#endif
21
22// ----------------------------------------------------------------------------
23// headers
24// ----------------------------------------------------------------------------
25
26// for compilers that support precompilation, includes "wx.h".
27#include "wx/wxprec.h"
28
29
30#ifndef WX_PRECOMP
31 #include "wx/wx.h"
32#endif
33
34#if wxUSE_SPINBTN
35
36#include "wx/spinctrl.h"
37#include "wx/os2/private.h"
38
39// ----------------------------------------------------------------------------
40// macros
41// ----------------------------------------------------------------------------
42
43extern void wxAssociateWinWithHandle( HWND hWnd
44 ,wxWindowOS2* pWin
45 );
46static WXFARPROC fnWndProcSpinCtrl = (WXFARPROC)NULL;
47wxArraySpins wxSpinCtrl::m_svAllSpins;
48
49IMPLEMENT_DYNAMIC_CLASS(wxSpinCtrl, wxControl)
50
51BEGIN_EVENT_TABLE(wxSpinCtrl, wxSpinButton)
52 EVT_SPIN(-1, wxSpinCtrl::OnSpinChange)
53END_EVENT_TABLE()
54// ----------------------------------------------------------------------------
55// constants
56// ----------------------------------------------------------------------------
57
58// the margin between the up-down control and its buddy
59static const int MARGIN_BETWEEN = 5;
60
61// ============================================================================
62// implementation
63// ============================================================================
64MRESULT EXPENTRY wxSpinCtrlWndProc(
65 HWND hWnd
66, UINT uMessage
67, MPARAM wParam
68, MPARAM lParam
69)
70{
71 wxSpinCtrl* pSpin = (wxSpinCtrl *)::WinQueryWindowULong( hWnd
72 ,QWL_USER
73 );
74 bool bProccesed = FALSE;
75 MRESULT rc = (MRESULT)0;
76 //
77 // Forward some messages (the key ones only so far) to the spin ctrl
78 //
79 switch (uMessage )
80 {
81 case WM_CHAR:
82 pSpin->OS2WindowProc( uMessage
83 ,wParam
84 ,lParam
85 );
86
87 //
88 // The control may have been deleted at this point, so check.
89 //
90 if (!(::WinIsWindow(vHabmain, hWnd) && ((wxSpinCtrl *)::WinQueryWindowULong( hWnd
91 ,QWL_USER
92 )
93 ) == pSpin))
94 return 0;
95 break;
96
97 }
98 return (fnWndProcSpinCtrl( hWnd
99 ,(ULONG)uMessage
100 ,(MPARAM)wParam
101 ,(MPARAM)lParam
102 )
103 );
104} // end of wxSpinCtrlWndProc
105
106wxSpinCtrl::~wxSpinCtrl()
107{
108 m_svAllSpins.Remove(this);
109
110 // This removes spurious memory leak reporting
111 if (m_svAllSpins.GetCount() == 0)
112 m_svAllSpins.Clear();
113} // end of wxSpinCtrl::~wxSpinCtrl
114
115// ----------------------------------------------------------------------------
116// construction
117// ----------------------------------------------------------------------------
118
119bool wxSpinCtrl::Create(
120 wxWindow* pParent
121, wxWindowID vId
122, const wxString& rsValue
123, const wxPoint& rPos
124, const wxSize& rSize
125, long lStyle
126, int nMin
127, int nMax
128, int nInitial
129, const wxString& rsName
130)
131{
132 SWP vSwp;
133
134 if (vId == -1)
135 m_windowId = NewControlId();
136 else
137 m_windowId = vId;
138 m_backgroundColour = pParent->GetBackgroundColour();
139 m_foregroundColour = pParent->GetForegroundColour();
140 SetName(rsName);
141 SetParent(pParent);
142 m_windowStyle = lStyle;
143
144 int lSstyle = 0L;
145
146 lSstyle = WS_VISIBLE |
147 WS_TABSTOP |
148 SPBS_MASTER | // We use only single field spin buttons
149 SPBS_NUMERICONLY; // We default to numeric data
150
151 if (m_windowStyle & wxCLIP_SIBLINGS )
152 lSstyle |= WS_CLIPSIBLINGS;
153
154 //
155 // If the parent is a scrolled window the controls must
156 // have this style or they will overlap the scrollbars
157 //
158 if (pParent)
159 if (pParent->IsKindOf(CLASSINFO(wxScrolledWindow)) ||
160 pParent->IsKindOf(CLASSINFO(wxGenericScrolledWindow)))
161 lSstyle |= WS_CLIPSIBLINGS;
162
163 SPBCDATA vCtrlData;
164
165 vCtrlData.cbSize = sizeof(SPBCDATA);
166 vCtrlData.ulTextLimit = 10L;
167 vCtrlData.lLowerLimit = 0L;
168 vCtrlData.lUpperLimit = 100L;
169 vCtrlData.idMasterSpb = vId;
170 vCtrlData.pHWXCtlData = NULL;
171
172 m_hWnd = (WXHWND)::WinCreateWindow( GetWinHwnd(pParent)
173 ,WC_SPINBUTTON
174 ,(PSZ)NULL
175 ,lSstyle
176 ,0L, 0L, 0L, 0L
177 ,GetWinHwnd(pParent)
178 ,HWND_TOP
179 ,(HMENU)vId
180 ,(PVOID)&vCtrlData
181 ,NULL
182 );
183 if (m_hWnd == 0)
184 {
185 return FALSE;
186 }
187 m_hWndBuddy = m_hWnd; // One in the same for OS/2
188 if(pParent)
189 pParent->AddChild((wxSpinButton *)this);
190 SetFont(*wxSMALL_FONT);
191 ::WinQueryWindowPos(m_hWnd, &vSwp);
192 SetXComp(vSwp.x);
193 SetYComp(vSwp.y);
194 SetSize( rPos.x
195 ,rPos.y
196 ,rSize.x
197 ,rSize.y
198 );
199
200 SetRange(nMin, nMax);
201 SetValue(nInitial);
202
203 //
204 // For OS/2 we'll just set our handle into our long data
205 //
206 wxAssociateWinWithHandle( m_hWnd
207 ,(wxWindowOS2*)this
208 );
209 ::WinSetWindowULong(GetHwnd(), QWL_USER, (LONG)this);
210 fnWndProcSpinCtrl = (WXFARPROC)::WinSubclassWindow(m_hWnd, (PFNWP)wxSpinCtrlWndProc);
211 m_svAllSpins.Add(this);
212 return TRUE;
213} // end of wxSpinCtrl::Create
214
215wxSize wxSpinCtrl::DoGetBestSize() const
216{
217 wxSize vSizeBtn = wxSpinButton::DoGetBestSize();
218 int nHeight;
219
220 vSizeBtn.x += DEFAULT_ITEM_WIDTH + MARGIN_BETWEEN;
221
222 wxGetCharSize( GetHWND()
223 ,NULL
224 ,&nHeight
225 ,(wxFont*)&GetFont()
226 );
227 nHeight = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nHeight);
228
229 if (vSizeBtn.y < nHeight)
230 {
231 //
232 // Make the text tall enough
233 //
234 vSizeBtn.y = nHeight;
235 }
236 return vSizeBtn;
237} // end of wxSpinCtrl::DoGetBestSize
238
239void wxSpinCtrl::DoGetPosition(
240 int* pnX
241, int* pnY
242) const
243{
244 WXHWND hWnd = GetHWND();
245
246 wxConstCast(this, wxSpinCtrl)->m_hWnd = m_hWndBuddy;
247 wxSpinButton::DoGetPosition( pnX
248 ,pnY
249 );
250 wxConstCast(this, wxSpinCtrl)->m_hWnd = hWnd;
251} // end of wxpinCtrl::DoGetPosition
252
253void wxSpinCtrl::DoGetSize(
254 int* pnWidth
255, int* pnHeight
256) const
257{
258 RECTL vSpinrect;
259
260 ::WinQueryWindowRect(GetHwnd(), &vSpinrect);
261
262 if (pnWidth)
263 *pnWidth = vSpinrect.xRight - vSpinrect.xLeft;
264 if (pnHeight)
265 *pnHeight = vSpinrect.yTop - vSpinrect.yBottom;
266} // end of wxSpinCtrl::DoGetSize
267
268void wxSpinCtrl::DoMoveWindow(
269 int nX
270, int nY
271, int nWidth
272, int nHeight
273)
274{
275 wxWindowOS2* pParent = (wxWindowOS2*)GetParent();
276
277 if (pParent)
278 {
279 int nOS2Height = GetOS2ParentHeight(pParent);
280
281 nY = nOS2Height - (nY + nHeight);
282 }
283 else
284 {
285 RECTL vRect;
286
287 ::WinQueryWindowRect(HWND_DESKTOP, &vRect);
288 nY = vRect.yTop - (nY + nHeight);
289 }
290 ::WinSetWindowPos( GetHwnd()
291 ,HWND_TOP
292 ,nX
293 ,nY
294 ,nWidth
295 ,nHeight
296 ,SWP_SIZE | SWP_MOVE | SWP_ZORDER | SWP_SHOW
297 );
298} // end of wxSpinCtrl::DoMoveWindow
299
300bool wxSpinCtrl::Enable(
301 bool bEnable
302)
303{
304 if (!wxControl::Enable(bEnable))
305 {
306 return FALSE;
307 }
308 ::WinEnableWindow(GetHwnd(), bEnable);
309 return TRUE;
310} // end of wxSpinCtrl::Enable
311
312wxSpinCtrl* wxSpinCtrl::GetSpinForTextCtrl(
313 WXHWND hWndBuddy
314)
315{
316 wxSpinCtrl* pSpin = (wxSpinCtrl *)::WinQueryWindowULong( (HWND)hWndBuddy
317 ,QWL_USER
318 );
319 int i = m_svAllSpins.Index(pSpin);
320
321 if (i == wxNOT_FOUND)
322 return NULL;
323
324 // sanity check
325 wxASSERT_MSG( pSpin->m_hWndBuddy == hWndBuddy,
326 _T("wxSpinCtrl has incorrect buddy HWND!") );
327
328 return pSpin;
329} // end of wxSpinCtrl::GetSpinForTextCtrl
330
331int wxSpinCtrl::GetValue() const
332{
333 long lVal = 0L;
334 char zVal[10];
335
336 ::WinSendMsg( GetHwnd()
337 ,SPBM_QUERYVALUE
338 ,MPFROMP(zVal)
339 ,MPFROM2SHORT( (USHORT)10
340 ,SPBQ_UPDATEIFVALID
341 )
342 );
343 lVal - atol(zVal);
344 return lVal;
345} // end of wxSpinCtrl::GetValue
346
347void wxSpinCtrl::OnChar (
348 wxKeyEvent& rEvent
349)
350{
351 switch (rEvent.KeyCode())
352 {
353 case WXK_RETURN:
354 {
355 wxCommandEvent vEvent( wxEVT_COMMAND_TEXT_ENTER
356 ,m_windowId
357 );
358 wxString sVal = wxGetWindowText(m_hWndBuddy);
359
360 InitCommandEvent(vEvent);
361 vEvent.SetString((char*)sVal.c_str());
362 vEvent.SetInt(GetValue());
363 if (GetEventHandler()->ProcessEvent(vEvent))
364 return;
365 break;
366 }
367
368 case WXK_TAB:
369 //
370 // Always produce navigation event - even if we process TAB
371 // ourselves the fact that we got here means that the user code
372 // decided to skip processing of this TAB - probably to let it
373 // do its default job.
374 //
375 {
376 wxNavigationKeyEvent vEventNav;
377
378 vEventNav.SetDirection(!rEvent.ShiftDown());
379 vEventNav.SetWindowChange(rEvent.ControlDown());
380 vEventNav.SetEventObject(this);
381 if (GetParent()->GetEventHandler()->ProcessEvent(vEventNav))
382 return;
383 }
384 break;
385 }
386
387 //
388 // No, we didn't process it
389 //
390 rEvent.Skip();
391} // end of wxSpinCtrl::OnChar
392
393void wxSpinCtrl::OnSpinChange(
394 wxSpinEvent& rEventSpin
395)
396{
397 wxCommandEvent vEvent( wxEVT_COMMAND_SPINCTRL_UPDATED
398 ,GetId()
399 );
400
401 vEvent.SetEventObject(this);
402 vEvent.SetInt(rEventSpin.GetPosition());
403 (void)GetEventHandler()->ProcessEvent(vEvent);
404 if (rEventSpin.GetSkipped())
405 {
406 vEvent.Skip();
407 }
408} // end of wxSpinCtrl::OnSpinChange
409
410bool wxSpinCtrl::ProcessTextCommand(
411 WXWORD wCmd
412, WXWORD wId
413)
414{
415 switch (wCmd)
416 {
417 case SPBN_CHANGE:
418 {
419 wxCommandEvent vEvent( wxEVT_COMMAND_TEXT_UPDATED
420 ,GetId()
421 );
422 vEvent.SetEventObject(this);
423
424 wxString sVal = wxGetWindowText(m_hWndBuddy);
425
426 vEvent.SetString((char*)sVal.c_str());
427 vEvent.SetInt(GetValue());
428 return (GetEventHandler()->ProcessEvent(vEvent));
429 }
430
431 case SPBN_SETFOCUS:
432 case SPBN_KILLFOCUS:
433 {
434 wxFocusEvent vEvent( wCmd == EN_KILLFOCUS ? wxEVT_KILL_FOCUS : wxEVT_SET_FOCUS
435 ,m_windowId
436 );
437
438 vEvent.SetEventObject(this);
439 return(GetEventHandler()->ProcessEvent(vEvent));
440 }
441 default:
442 break;
443 }
444
445 //
446 // Not processed
447 //
448 return FALSE;
449} // end of wxSpinCtrl::ProcessTextCommand
450
451void wxSpinCtrl::SetFocus()
452{
453 ::WinSetFocus(HWND_DESKTOP, GetHwnd());
454} // end of wxSpinCtrl::SetFocus
455
456bool wxSpinCtrl::SetFont(
457 const wxFont& rFont
458)
459{
460 if (!wxWindowBase::SetFont(rFont))
461 {
462 // nothing to do
463 return FALSE;
464 }
465
466 WXHANDLE hFont = GetFont().GetResourceHandle();
467 wxOS2SetFont( m_hWnd
468 ,rFont
469 );
470 return TRUE;
471} // end of wxSpinCtrl::SetFont
472
473void wxSpinCtrl::SetValue(
474 const wxString& rsText
475)
476{
477 long lVal;
478
479 lVal = atol(rsText.c_str());
480 wxSpinButton::SetValue(lVal);
481} // end of wxSpinCtrl::SetValue
482
483bool wxSpinCtrl::Show(
484 bool bShow
485)
486{
487 if (!wxControl::Show(bShow))
488 {
489 return FALSE;
490 }
491 return TRUE;
492} // end of wxSpinCtrl::Show
493
494#endif //wxUSE_SPINBTN