'Y' positioning fixes for OS/2 controls
[wxWidgets.git] / src / os2 / slider.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: slider.cpp
3 // Purpose: wxSlider
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 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18
19 #ifndef WX_PRECOMP
20 #include <stdio.h>
21 #include <wx/utils.h>
22 #include <wx/brush.h>
23 #endif
24
25 #include "wx/slider.h"
26 #include "wx/os2/private.h"
27
28 IMPLEMENT_DYNAMIC_CLASS(wxSlider, wxControl)
29
30 wxSlider::wxSlider()
31 {
32 m_hStaticValue = 0L;
33 m_hStaticMin = 0L;
34 m_hStaticMax = 0L;
35 m_nPageSize = 1;
36 m_nLineSize = 1;
37 m_nRangeMax = 0;
38 m_nRangeMin = 0;
39 m_nTickFreq = 0;
40 } // end of wxSlider::wxSlider
41
42 wxSlider::~wxSlider()
43 {
44 if (m_hStaticMin)
45 ::WinDestroyWindow((HWND)m_hStaticMin);
46 if (m_hStaticMax)
47 ::WinDestroyWindow((HWND)m_hStaticMax);
48 if (m_hStaticValue)
49 ::WinDestroyWindow((HWND)m_hStaticValue);
50 } // end of wxSlider::~wxSlider
51
52 void wxSlider::AdjustSubControls(
53 int nX
54 , int nY
55 , int nWidth
56 , int nHeight
57 , int nSizeFlags
58 )
59 {
60 SWP vSwp;
61 int nXOffset = nX;
62 int nYOffset = nY;
63 int nCx; // slider,min,max sizes
64 int nCy;
65 int nCyf;
66 char zBuf[300];
67
68 wxGetCharSize( GetHWND()
69 ,&nCx
70 ,&nCy
71 ,&this->GetFont()
72 );
73
74 if ((m_windowStyle & wxSL_VERTICAL) != wxSL_VERTICAL)
75 {
76 if (m_windowStyle & wxSL_LABELS )
77 {
78 int nMinLen = 0;
79 int nMaxLen = 0;
80
81 ::WinQueryWindowText((HWND)m_hStaticMin, 300, zBuf);
82 GetTextExtent(zBuf, &nMinLen, &nCyf, NULL, NULL, &this->GetFont());
83
84 ::WinQueryWindowText((HWND)m_hStaticMax, 300, zBuf);
85 GetTextExtent(zBuf, &nMaxLen, &nCyf, NULL, NULL, &this->GetFont());
86
87 if (m_hStaticValue)
88 {
89 int nNewWidth = wxMax(nMinLen, nMaxLen);
90 int nValueHeight = nCyf;
91
92 ::WinSetWindowPos( (HWND)m_hStaticValue
93 ,HWND_TOP
94 ,(LONG)nXOffset - (nNewWidth + nCx + nMinLen + nCx)
95 ,(LONG)nYOffset
96 ,(LONG)nNewWidth
97 ,(LONG)nValueHeight
98 ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
99 );
100 }
101 ::WinSetWindowPos( (HWND)m_hStaticMin
102 ,HWND_TOP
103 ,(LONG)nXOffset - (nMinLen + nCx)
104 ,(LONG)nYOffset
105 ,(LONG)nMinLen
106 ,(LONG)nCy
107 ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
108 );
109 nXOffset += nWidth + nCx;
110
111 ::WinSetWindowPos( (HWND)m_hStaticMax
112 ,HWND_TOP
113 ,(LONG)nXOffset
114 ,(LONG)nYOffset
115 ,(LONG)nMaxLen
116 ,(LONG)nCy
117 ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
118 );
119 }
120 }
121 //
122 // Now deal with a vertical slider -- OS/2 doesn't have vertical sliders
123 //
124 } // end of wxSlider::AdjustSubControls
125
126 void wxSlider::ClearSel()
127 {
128 } // end of wxSlider::ClearSel
129
130 void wxSlider::ClearTicks()
131 {
132 } // end of wxSlider::ClearTicks
133
134 void wxSlider::Command (
135 wxCommandEvent& rEvent
136 )
137 {
138 SetValue(rEvent.GetInt());
139 ProcessCommand(rEvent);
140 } // end of wxSlider::Command
141
142 bool wxSlider::ContainsHWND(
143 WXHWND hWnd
144 ) const
145 {
146 return ( hWnd == GetStaticMin() ||
147 hWnd == GetStaticMax() ||
148 hWnd == GetEditValue()
149 );
150 } // end of wxSlider::ContainsHWND
151
152 bool wxSlider::Create(
153 wxWindow* pParent
154 , wxWindowID vId
155 , int nValue
156 , int nMinValue
157 , int nMaxValue
158 , const wxPoint& rPos
159 , const wxSize& rSize
160 , long lStyle
161 #if wxUSE_VALIDATORS
162 , const wxValidator& rValidator
163 #endif
164 , const wxString& rsName
165 )
166 {
167 int nX = rPos.x;
168 int nY = rPos.y;
169 int nWidth = rSize.x;
170 int nHeight = rSize.y;
171 long lMsStyle = 0L;
172 long lWstyle = 0L;
173
174 SetName(rsName);
175 #if wxUSE_VALIDATORS
176 SetValidator(rValidator);
177 #endif
178 if (pParent)
179 pParent->AddChild(this);
180 SetBackgroundColour(pParent->GetBackgroundColour()) ;
181 SetForegroundColour(pParent->GetForegroundColour()) ;
182
183 m_hStaticValue = 0L;
184 m_hStaticMin = 0L;
185 m_hStaticMax = 0L;
186 m_nPageSize = 1;
187 m_nLineSize = 1;
188 m_windowStyle = lStyle;
189 m_nTickFreq = 0;
190
191 if (vId == -1)
192 m_windowId = (int)NewControlId();
193 else
194 m_windowId = vId;
195
196 if (m_windowStyle & wxCLIP_SIBLINGS )
197 lMsStyle |= WS_CLIPSIBLINGS;
198
199 if (m_windowStyle & wxSL_LABELS)
200 {
201 lMsStyle |= WS_VISIBLE | SS_TEXT | DT_VCENTER;
202
203 m_hStaticValue = (WXHWND)::WinCreateWindow( (HWND)GetHwndOf(pParent) // Parent window handle
204 ,WC_STATIC // Window class
205 ,(PSZ)NULL // Initial Text
206 ,(ULONG)lMsStyle // Style flags
207 ,0L, 0L, 0L, 0L // Origin -- 0 size
208 ,(HWND)GetHwndOf(pParent) // owner window handle (same as parent
209 ,HWND_TOP // initial z position
210 ,(ULONG)NewControlId() // Window identifier
211 ,NULL // no control data
212 ,NULL // no Presentation parameters
213 );
214
215 //
216 // Now create min static control
217 //
218 sprintf(wxBuffer, "%d", nMinValue);
219 lWstyle = SS_TEXT|DT_LEFT|WS_VISIBLE;
220 if (m_windowStyle & wxCLIP_SIBLINGS)
221 lWstyle |= WS_CLIPSIBLINGS;
222 m_hStaticMin = (WXHWND)::WinCreateWindow( (HWND)GetHwndOf(pParent) // Parent window handle
223 ,WC_STATIC // Window class
224 ,(PSZ)wxBuffer // Initial Text
225 ,(ULONG)lWstyle // Style flags
226 ,0L, 0L, 0L, 0L // Origin -- 0 size
227 ,(HWND)GetHwndOf(pParent) // owner window handle (same as parent
228 ,HWND_TOP // initial z position
229 ,(ULONG)NewControlId() // Window identifier
230 ,NULL // no control data
231 ,NULL // no Presentation parameters
232 );
233 }
234 lMsStyle = 0;
235
236 SLDCDATA vSlData;
237
238 vSlData.cbSize = sizeof(SLDCDATA);
239 if (m_windowStyle & wxSL_VERTICAL)
240 lMsStyle = SLS_VERTICAL | WS_VISIBLE | WS_TABSTOP;
241 else
242 lMsStyle = SLS_HORIZONTAL | WS_VISIBLE | WS_TABSTOP;
243
244 if (m_windowStyle & wxCLIP_SIBLINGS)
245 lMsStyle |= WS_CLIPSIBLINGS;
246
247 if (m_windowStyle & wxSL_AUTOTICKS)
248 {
249 vSlData.usScale1Spacing = 0;
250 vSlData.usScale2Spacing = 0;
251 }
252
253 if (m_windowStyle & wxSL_LEFT)
254 lMsStyle |= SLS_PRIMARYSCALE2; // if SLS_VERTICAL then SCALE2 is to the left
255 else if (m_windowStyle & wxSL_RIGHT)
256 lMsStyle |= SLS_PRIMARYSCALE1; // if SLS_VERTICAL then SCALE2 is to the right
257 else if (m_windowStyle & wxSL_TOP)
258 lMsStyle |= SLS_PRIMARYSCALE1; // if SLS_HORIZONTAL then SCALE1 is to the top
259 else if (m_windowStyle & wxSL_BOTTOM )
260 lMsStyle |= SLS_PRIMARYSCALE2; // if SLS_HORIZONTAL then SCALE1 is to the bottom
261 else if ( m_windowStyle & wxSL_BOTH )
262 lMsStyle |= SLS_PRIMARYSCALE1 | SLS_PRIMARYSCALE2;
263 else
264 lMsStyle |= SLS_PRIMARYSCALE2;
265
266 m_nPageSize = ((nMaxValue - nMinValue)/10);
267 vSlData.usScale1Increments = m_nPageSize;
268 vSlData.usScale2Increments = m_nPageSize;
269
270 HWND hScrollBar = ::WinCreateWindow( (HWND)GetHwndOf(pParent) // Parent window handle
271 ,WC_SLIDER // Window class
272 ,(PSZ)wxBuffer // Initial Text
273 ,(ULONG)lMsStyle // Style flags
274 ,0L, 0L, 0L, 0L // Origin -- 0 size
275 ,(HWND)GetHwndOf(pParent) // owner window handle (same as parent
276 ,HWND_TOP // initial z position
277 ,(HMENU)m_windowId // Window identifier
278 ,&vSlData // Slider control data
279 ,NULL // no Presentation parameters
280 );
281 m_nRangeMax = nMaxValue;
282 m_nRangeMin = nMinValue;
283
284 //
285 // Set the size of the ticks ... default to 6 pixels
286 //
287 ::WinSendMsg( hScrollBar
288 ,SLM_SETTICKSIZE
289 ,MPFROM2SHORT(SMA_SETALLTICKS, 6)
290 ,NULL
291 );
292 //
293 // Set the position to the initial value
294 //
295 ::WinSendMsg( hScrollBar
296 ,SLM_SETSLIDERINFO
297 ,MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_RANGEVALUE)
298 ,(MPARAM)nValue
299 );
300
301 m_hWnd = (WXHWND)hScrollBar;
302 SubclassWin(GetHWND());
303 ::WinSetWindowText((HWND)m_hWnd, "");
304 SetFont(pParent->GetFont());
305 if (m_windowStyle & wxSL_LABELS)
306 {
307 //
308 // Finally, create max value static item
309 //
310 sprintf(wxBuffer, "%d", nMaxValue);
311 lWstyle = SS_TEXT|DT_LEFT|WS_VISIBLE;
312 if (m_windowStyle & wxCLIP_SIBLINGS)
313 lMsStyle |= WS_CLIPSIBLINGS;
314 m_hStaticMax = (WXHWND)::WinCreateWindow( (HWND)GetHwndOf(pParent) // Parent window handle
315 ,WC_STATIC // Window class
316 ,(PSZ)wxBuffer // Initial Text
317 ,(ULONG)lWstyle // Style flags
318 ,0L, 0L, 0L, 0L // Origin -- 0 size
319 ,(HWND)GetHwndOf(pParent) // owner window handle (same as parent
320 ,HWND_TOP // initial z position
321 ,(ULONG)NewControlId() // Window identifier
322 ,NULL // no control data
323 ,NULL // no Presentation parameters
324 );
325 if (GetFont().Ok())
326 {
327 if (GetFont().GetResourceHandle())
328 {
329 if (m_hStaticMin)
330 wxOS2SetFont( m_hStaticMin
331 ,GetFont()
332 );
333 if (m_hStaticMax)
334 wxOS2SetFont( m_hStaticMax
335 ,GetFont()
336 );
337 if (m_hStaticValue)
338 wxOS2SetFont( m_hStaticValue
339 ,GetFont()
340 );
341 }
342 }
343 }
344
345 SetSize( nX
346 ,nY
347 ,nWidth
348 ,nHeight
349 );
350 m_nThumbLength = SHORT1FROMMR(::WinSendMsg( GetHwnd()
351 ,SLM_QUERYSLIDERINFO
352 ,MPFROM2SHORT( SMA_SLIDERARMDIMENSIONS
353 ,SMA_RANGEVALUE
354 )
355 ,(MPARAM)0
356 )
357 ) + 4; // for bordersizes
358
359 wxColour vColour;
360
361 vColour.Set(wxString("BLACK"));
362
363 LONG lColor = (LONG)vColour.GetPixel();
364
365 ::WinSetPresParam( m_hStaticMin
366 ,PP_FOREGROUNDCOLOR
367 ,sizeof(LONG)
368 ,(PVOID)&lColor
369 );
370 ::WinSetPresParam( m_hStaticMax
371 ,PP_FOREGROUNDCOLOR
372 ,sizeof(LONG)
373 ,(PVOID)&lColor
374 );
375 ::WinSetPresParam( m_hStaticValue
376 ,PP_FOREGROUNDCOLOR
377 ,sizeof(LONG)
378 ,(PVOID)&lColor
379 );
380 ::WinSetPresParam( m_hWnd
381 ,PP_FOREGROUNDCOLOR
382 ,sizeof(LONG)
383 ,(PVOID)&lColor
384 );
385 SetValue(nValue);
386 return TRUE;
387 } // end of wxSlider::Create
388
389 void wxSlider::DoSetSize(
390 int nX
391 , int nY
392 , int nWidth
393 , int nHeight
394 , int nSizeFlags
395 )
396 {
397 int nX1 = nX;
398 int nY1 = nY;
399 int nWidth1 = nWidth;
400 int nHeight1 = nHeight;
401 int nXOffset = nX;
402 int nYOffset = nY;
403 int nCx; // slider,min,max sizes
404 int nCy;
405 int nCyf;
406 int nCurrentX;
407 int nCurrentY;
408 char zBuf[300];
409
410 //
411 // Adjust for OS/2's reverse coordinate system
412 //
413 wxWindowOS2* pParent = (wxWindowOS2*)GetParent();
414 int nUsedHeight = 0;
415 int nOS2Height = nHeight;
416
417 if (nOS2Height < 0)
418 nOS2Height = 20;
419
420 if (pParent)
421 {
422 int nOS2ParentHeight = GetOS2ParentHeight(pParent);
423
424 nYOffset = nOS2ParentHeight - (nYOffset + nOS2Height);
425 if (nY != -1)
426 nY1 = nOS2ParentHeight - (nY1 + nOS2Height);
427 }
428 else
429 {
430 RECTL vRect;
431
432 ::WinQueryWindowRect(HWND_DESKTOP, &vRect);
433 nYOffset = vRect.yTop - (nYOffset + nOS2Height);
434 if (nY != -1)
435 nY1 = vRect.yTop - (nY1 + nOS2Height);
436 }
437 m_nSizeFlags = nSizeFlags;
438
439 GetPosition( &nCurrentX
440 ,&nCurrentY
441 );
442 if (nX == -1 && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
443 nX1 = nCurrentX;
444 if (nY == -1 && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
445 nY1 = nCurrentY;
446
447 AdjustForParentClientOrigin( nX1
448 ,nY1
449 ,nSizeFlags
450 );
451 wxGetCharSize( GetHWND()
452 ,&nCx
453 ,&nCy
454 ,&this->GetFont()
455 );
456
457 if ((m_windowStyle & wxSL_VERTICAL) != wxSL_VERTICAL)
458 {
459 if (m_windowStyle & wxSL_LABELS )
460 {
461 int nMinLen = 0;
462 int nMaxLen = 0;
463
464 ::WinQueryWindowText((HWND)m_hStaticMin, 300, zBuf);
465 GetTextExtent(zBuf, &nMinLen, &nCyf, NULL, NULL, &this->GetFont());
466 ::WinQueryWindowText((HWND)m_hStaticMax, 300, zBuf);
467 GetTextExtent(zBuf, &nMaxLen, &nCyf, NULL, NULL, &this->GetFont());
468
469 if (m_hStaticValue)
470 {
471 int nNewWidth = (wxMax(nMinLen, nMaxLen));
472 int nValueHeight = nCyf;
473
474 ::WinSetWindowPos( (HWND)m_hStaticValue
475 ,HWND_TOP
476 ,(LONG)nXOffset
477 ,(LONG)nYOffset - (nCyf * 1.2)
478 ,(LONG)nNewWidth
479 ,(LONG)nValueHeight
480 ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
481 );
482 nXOffset += nNewWidth + nCx;
483 }
484 ::WinSetWindowPos( (HWND)m_hStaticMin
485 ,HWND_TOP
486 ,(LONG)nXOffset
487 ,(LONG)nYOffset - nCyf
488 ,(LONG)nMinLen
489 ,(LONG)nCy
490 ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
491 );
492 nXOffset += nMinLen + nCx;
493
494 int nSliderLength = nWidth1 - nXOffset - nMaxLen - nCx;
495 int nSliderHeight = nHeight1;
496
497 if (nSliderHeight < 0)
498 nSliderHeight = 20;
499
500 //
501 // Slider must have a minimum/default length/height
502 //
503 if (nSliderLength < 100)
504 nSliderLength = 100;
505
506 ::WinSetWindowPos( GetHwnd()
507 ,HWND_TOP
508 ,(LONG)nXOffset
509 ,(LONG)nYOffset
510 ,(LONG)nSliderLength
511 ,(LONG)nSliderHeight
512 ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
513 );
514 nXOffset += nSliderLength + nCx;
515
516 ::WinSetWindowPos( (HWND)m_hStaticMax
517 ,HWND_TOP
518 ,(LONG)nXOffset
519 ,(LONG)nYOffset - nCyf
520 ,(LONG)nMaxLen
521 ,(LONG)nCy
522 ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
523 );
524 }
525 else
526 {
527 //
528 // No labels
529 // If we're prepared to use the existing size, then...
530 //
531 if (nWidth == -1 && nHeight == -1 &&
532 ((nSizeFlags & wxSIZE_AUTO) != wxSIZE_AUTO))
533 {
534 GetSize( &nWidth1
535 ,&nHeight1
536 );
537 }
538 if (nWidth1 < 0)
539 nWidth1 = 200;
540 if (nHeight1 < 0)
541 nHeight1 = 20;
542 ::WinSetWindowPos( GetHwnd()
543 ,HWND_TOP
544 ,(LONG)nX1
545 ,(LONG)nY1
546 ,(LONG)nWidth1
547 ,(LONG)nHeight1
548 ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
549 );
550 }
551 }
552
553 //
554 // Now deal with a vertical slider
555 //
556 else
557 {
558 if (m_windowStyle & wxSL_LABELS )
559 {
560 int nMinLen;
561 int nMaxLen;
562
563 ::WinQueryWindowText((HWND)m_hStaticMin, 300, zBuf);
564 GetTextExtent(zBuf, &nMinLen, &nCyf, NULL, NULL, &this->GetFont());
565 ::WinQueryWindowText((HWND)m_hStaticMax, 300, zBuf);
566 GetTextExtent(zBuf, &nMaxLen, &nCyf, NULL, NULL, &this->GetFont());
567 if (m_hStaticValue)
568 {
569 int nNewWidth = wxMax(nMinLen, nMaxLen);
570 int nValueHeight = nCyf;
571
572 nNewWidth += nCx;
573
574 //
575 // The height needs to be a bit bigger under Win95 if using native
576 // 3D effects.
577 //
578 nValueHeight = (int)(nValueHeight * 1.5);
579 ::WinSetWindowPos( (HWND)m_hStaticValue
580 ,HWND_TOP
581 ,(LONG)nXOffset
582 ,(LONG)nYOffset
583 ,(LONG)nNewWidth
584 ,(LONG)nValueHeight
585 ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
586 );
587 nYOffset -= nValueHeight;
588 nUsedHeight += nValueHeight;
589 }
590 ::WinSetWindowPos( (HWND)m_hStaticMin
591 ,HWND_TOP
592 ,(LONG)nXOffset
593 ,(LONG)nYOffset
594 ,(LONG)nMinLen
595 ,(LONG)nCy
596 ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
597 );
598 nYOffset -= nCy;
599 nUsedHeight += nCy;
600
601 int nSliderLength = nHeight1 - (nUsedHeight + (2 * nCy));
602 int nSliderWidth = nWidth1;
603
604 if (nSliderWidth < 0)
605 nSliderWidth = 20;
606
607 //
608 // Slider must have a minimum/default length
609 //
610 if (nSliderLength < 100)
611 nSliderLength = 100;
612
613 ::WinSetWindowPos( (HWND)m_hStaticMin
614 ,HWND_TOP
615 ,(LONG)nXOffset
616 ,(LONG)nYOffset
617 ,(LONG)nSliderWidth
618 ,(LONG)nSliderLength
619 ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
620 );
621 nYOffset -= nSliderLength;
622 nUsedHeight += nSliderLength;
623 ::WinSetWindowPos( (HWND)m_hStaticMax
624 ,HWND_TOP
625 ,(LONG)nXOffset
626 ,(LONG)nYOffset
627 ,(LONG)nMaxLen
628 ,(LONG)nCy
629 ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
630 );
631 }
632 else
633 {
634 //
635 // No labels
636 // If we're prepared to use the existing size, then...
637 //
638 if (nWidth == -1 && nHeight == -1 &&
639 ((nSizeFlags & wxSIZE_AUTO) != wxSIZE_AUTO))
640 {
641 GetSize( &nWidth1
642 ,&nHeight1
643 );
644 }
645 if (nWidth1 < 0)
646 nWidth1 = 20;
647 if (nHeight1 < 0)
648 nHeight1 = 200;
649 ::WinSetWindowPos( GetHwnd()
650 ,HWND_TOP
651 ,(LONG)nX1
652 ,(LONG)nY1
653 ,(LONG)nWidth1
654 ,(LONG)nHeight1
655 ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
656 );
657 }
658 }
659 } // end of void wxSlider::DoSetSize
660
661 int wxSlider::GetLineSize() const
662 {
663 return 1;
664 } // end of wxSlider::GetLineSize
665
666 int wxSlider::GetPageSize() const
667 {
668 return m_nPageSize;
669 } // end of wxSlider::GetPageSize
670
671 void wxSlider::GetPosition(
672 int* pnX
673 , int* pnY
674 ) const
675 {
676 wxWindowOS2* pParent = GetParent();
677 RECTL vRect;
678
679 vRect.xLeft = -1;
680 vRect.xRight = -1;
681 vRect.yTop = -1;
682 vRect.yBottom = -1;
683 wxFindMaxSize( GetHWND()
684 ,&vRect
685 );
686
687 if (m_hStaticMin)
688 wxFindMaxSize( m_hStaticMin
689 ,&vRect
690 );
691 if (m_hStaticMax)
692 wxFindMaxSize( m_hStaticMax
693 ,&vRect
694 );
695 if (m_hStaticValue)
696 wxFindMaxSize( m_hStaticValue
697 ,&vRect
698 );
699
700 //
701 // Since we now have the absolute screen coords,
702 // if there's a parent we must subtract its top left corner
703 //
704 POINTL vPoint;
705
706 vPoint.x = vRect.xLeft;
707 vPoint.y = vRect.yTop;
708
709 if (pParent)
710 {
711 SWP vSwp;
712
713 ::WinQueryWindowPos((HWND)pParent->GetHWND(), &vSwp);
714 vPoint.x = vSwp.x;
715 vPoint.y = vSwp.y;
716 }
717
718 //
719 // We may be faking the client origin.
720 // So a window that's really at (0, 30) may appear
721 // (to wxWin apps) to be at (0, 0).
722 //
723 if (GetParent())
724 {
725 wxPoint vPt(GetParent()->GetClientAreaOrigin());
726
727 vPoint.x -= vPt.x;
728 vPoint.y -= vPt.y;
729 }
730 *pnX = vPoint.x;
731 *pnY = vPoint.y;
732 } // end of wxSlider::GetPosition
733
734 int wxSlider::GetSelEnd() const
735 {
736 return 0;
737 } // end of wxSlider::GetSelEnd
738
739 int wxSlider::GetSelStart() const
740 {
741 return 0;
742 } // end of wxSlider::GetSelStart
743
744 void wxSlider::GetSize(
745 int* pnWidth
746 , int* pnHeight
747 ) const
748 {
749 RECTL vRect;
750
751 vRect.xLeft = -1;
752 vRect.xRight = -1;
753 vRect.yTop = -1;
754 vRect.yBottom = -1;
755
756 wxFindMaxSize( GetHWND()
757 ,&vRect
758 );
759
760 if (m_hStaticMin)
761 wxFindMaxSize( m_hStaticMin
762 ,&vRect
763 );
764 if (m_hStaticMax)
765 wxFindMaxSize( m_hStaticMax
766 ,&vRect
767 );
768 if (m_hStaticValue)
769 wxFindMaxSize( m_hStaticValue
770 ,&vRect
771 );
772 *pnWidth = vRect.xRight - vRect.xLeft;
773 *pnHeight = vRect.yBottom - vRect.yTop;
774 } // end of wxSlider::GetSize
775
776 int wxSlider::GetThumbLength() const
777 {
778 return m_nThumbLength;
779 } // end of wxSlider::GetThumbLength
780
781 int wxSlider::GetValue() const
782 {
783 int nPixelRange = SHORT1FROMMR(::WinSendMsg( GetHwnd()
784 ,SLM_QUERYSLIDERINFO
785 ,MPFROM2SHORT( SMA_SHAFTDIMENSIONS
786 ,SMA_RANGEVALUE
787 )
788 ,(MPARAM)0
789 )
790 );
791 double dPixelToRange = (double)(nPixelRange - m_nThumbLength)/(double)(m_nRangeMax - m_nRangeMin);
792 int nNewPos = 0;
793 int nPixelPos = SHORT1FROMMR(::WinSendMsg( GetHwnd()
794 ,SLM_QUERYSLIDERINFO
795 ,MPFROM2SHORT( SMA_SLIDERARMPOSITION
796 ,SMA_RANGEVALUE
797 )
798 ,(MPARAM)0
799 )
800 );
801 nNewPos = (int)(nPixelPos/dPixelToRange);
802 if (nNewPos > (m_nRangeMax - m_nRangeMin)/2)
803 nNewPos++;
804 return nNewPos;
805 } // end of wxSlider::GetValue
806
807 WXHBRUSH wxSlider::OnCtlColor(
808 WXHDC hDC
809 , WXHWND hWnd
810 , WXUINT uCtlColor
811 , WXUINT uMessage
812 , WXWPARAM wParam
813 , WXLPARAM lParam
814 )
815 {
816 return (wxControl::OnCtlColor( hDC
817 ,hWnd
818 ,uCtlColor
819 ,uMessage
820 ,wParam
821 ,lParam
822 )
823 );
824 } // end of wxSlider::OnCtlColor
825
826 bool wxSlider::OS2OnScroll(
827 int WXUNUSED(nOrientation)
828 , WXWORD wParam
829 , WXWORD wPos
830 , WXHWND hControl
831 )
832 {
833 wxEventType eScrollEvent = wxEVT_NULL;
834
835 switch (wParam)
836 {
837 case SLN_CHANGE:
838 if (m_windowStyle & wxSL_TOP)
839 eScrollEvent = wxEVT_SCROLL_TOP;
840 else if (m_windowStyle & wxSL_BOTTOM)
841 eScrollEvent = wxEVT_SCROLL_BOTTOM;
842 break;
843
844 case SLN_SLIDERTRACK:
845 eScrollEvent = wxEVT_SCROLL_THUMBTRACK;
846 break;
847
848 default:
849 return FALSE;
850 }
851
852 int nPixelRange = SHORT1FROMMR(::WinSendMsg( GetHwnd()
853 ,SLM_QUERYSLIDERINFO
854 ,MPFROM2SHORT( SMA_SHAFTDIMENSIONS
855 ,SMA_RANGEVALUE
856 )
857 ,(MPARAM)0
858 )
859 );
860 m_dPixelToRange = (double)(nPixelRange - m_nThumbLength)/(double)(m_nRangeMax - m_nRangeMin);
861 int nNewPos = 0;
862 int nPixelPos = SHORT1FROMMR(::WinSendMsg( GetHwnd()
863 ,SLM_QUERYSLIDERINFO
864 ,MPFROM2SHORT( SMA_SLIDERARMPOSITION
865 ,SMA_RANGEVALUE
866 )
867 ,(MPARAM)0
868 )
869 );
870 nNewPos = (nPixelPos/m_dPixelToRange);
871 if (nNewPos > (m_nRangeMax - m_nRangeMin)/2)
872 nNewPos++;
873 if ((nNewPos < GetMin()) || (nNewPos > GetMax()))
874 {
875 //
876 // Out of range - but we did process it
877 //
878 return TRUE;
879 }
880 SetValue(nNewPos);
881
882 wxScrollEvent vEvent( eScrollEvent
883 ,m_windowId
884 );
885
886 vEvent.SetPosition(nNewPos);
887 vEvent.SetEventObject(this);
888 GetEventHandler()->ProcessEvent(vEvent);
889
890 wxCommandEvent vCevent( wxEVT_COMMAND_SLIDER_UPDATED
891 ,GetId()
892 );
893
894 vCevent.SetInt(nNewPos);
895 vCevent.SetEventObject(this);
896 return (GetEventHandler()->ProcessEvent(vCevent));
897 } // end of wxSlider::OS2OnScroll
898
899 void wxSlider::SetLineSize(
900 int nLineSize
901 )
902 {
903 m_nLineSize = nLineSize;
904 } // end of wxSlider::SetLineSize
905
906
907 void wxSlider::SetPageSize(
908 int nPageSize
909 )
910 {
911 m_nPageSize = nPageSize;
912 } // end of wxSlider::SetPageSize
913
914 void wxSlider::SetRange(
915 int nMinValue
916 , int nMaxValue
917 )
918 {
919 wxChar zBuf[10];
920
921 m_nRangeMin = nMinValue;
922 m_nRangeMax = nMaxValue;
923
924 int nPixelRange = SHORT1FROMMR(::WinSendMsg( GetHwnd()
925 ,SLM_QUERYSLIDERINFO
926 ,MPFROM2SHORT( SMA_SHAFTDIMENSIONS
927 ,SMA_RANGEVALUE
928 )
929 ,(MPARAM)0
930 )
931 );
932 m_dPixelToRange = (double)(nPixelRange - m_nThumbLength)/(double)(m_nRangeMax - m_nRangeMin);
933 if (m_hStaticMin)
934 {
935 wxSprintf(zBuf, wxT("%d"), m_nRangeMin);
936 ::WinSetWindowText((HWND)m_hStaticMin, zBuf);
937 }
938
939 if (m_hStaticMax)
940 {
941 wxSprintf(zBuf, wxT("%d"), m_nRangeMax);
942 ::WinSetWindowText((HWND)m_hStaticMax, zBuf);
943 }
944 } // end of wxSlider::SetRange
945
946 void wxSlider::SetSelection(
947 int WXUNUSED(nMinPos)
948 , int WXUNUSED(nMaxPos)
949 )
950 {
951 } // end of wxSlider::SetSelection
952
953 void wxSlider::SetThumbLength(
954 int nLen
955 )
956 {
957 int nBreadth;
958
959 m_nThumbLength = SHORT1FROMMR(::WinSendMsg( GetHwnd()
960 ,SLM_QUERYSLIDERINFO
961 ,MPFROM2SHORT( SMA_SLIDERARMDIMENSIONS
962 ,SMA_RANGEVALUE
963 )
964 ,(MPARAM)0
965 )
966 ) + 4; // for bordersizes
967 nBreadth = SHORT2FROMMR(::WinSendMsg( GetHwnd()
968 ,SLM_QUERYSLIDERINFO
969 ,MPFROM2SHORT( SMA_SLIDERARMDIMENSIONS
970 ,SMA_RANGEVALUE
971 )
972 ,(MPARAM)0
973 )
974 );
975 ::WinSendMsg( GetHwnd()
976 ,SLM_SETSLIDERINFO
977 ,MPFROM2SHORT( SMA_SLIDERARMDIMENSIONS
978 ,SMA_RANGEVALUE
979 )
980 ,MPFROM2SHORT(nLen, nBreadth)
981 );
982 m_nThumbLength = nLen + 4; // Borders
983 } // end of wxSlider::SetThumbLength
984
985 void wxSlider::SetTick(
986 int nTickPos
987 )
988 {
989 nTickPos *= m_dPixelToRange;
990 ::WinSendMsg( GetHwnd()
991 ,SLM_ADDDETENT
992 ,MPFROMSHORT(nTickPos)
993 ,NULL
994 );
995 } // end of wxSlider::SetTick
996
997 // For trackbars only
998 void wxSlider::SetTickFreq(
999 int n
1000 , int nPos
1001 )
1002 {
1003 SLDCDATA vSlData;
1004 WNDPARAMS vWndParams;
1005 int nPixelPos;
1006 int i;
1007
1008 vSlData.cbSize = sizeof(SLDCDATA);
1009 if (m_windowStyle & wxSL_AUTOTICKS)
1010 {
1011 vSlData.usScale1Spacing = 0;
1012 vSlData.usScale2Spacing = 0;
1013 }
1014 vSlData.usScale1Increments = (m_nRangeMax - m_nRangeMin)/n;
1015 vSlData.usScale2Increments = (m_nRangeMax - m_nRangeMin)/n;
1016
1017 vWndParams.fsStatus = WPM_CTLDATA;
1018 vWndParams.cchText = 0L;
1019 vWndParams.pszText = NULL;
1020 vWndParams.cbPresParams = 0L;
1021 vWndParams.pPresParams = NULL;
1022 vWndParams.cbCtlData = vSlData.cbSize;
1023 vWndParams.pCtlData = (PVOID)&vSlData;
1024 ::WinSendMsg(GetHwnd(), WM_SETWINDOWPARAMS, (MPARAM)&vWndParams, (MPARAM)0);
1025 for (i = 1; i < (m_nRangeMax - m_nRangeMin)/n; i++)
1026 {
1027 nPixelPos = i * n * m_dPixelToRange;
1028 ::WinSendMsg( GetHwnd()
1029 ,SLM_ADDDETENT
1030 ,MPFROMSHORT(nPixelPos)
1031 ,NULL
1032 );
1033 }
1034 } // end of wxSlider::SetTickFreq
1035
1036 void wxSlider::SetValue(
1037 int nValue
1038 )
1039 {
1040 int nPixelPos = SHORT1FROMMR(::WinSendMsg( GetHwnd()
1041 ,SLM_QUERYSLIDERINFO
1042 ,MPFROM2SHORT( SMA_SLIDERARMPOSITION
1043 ,SMA_RANGEVALUE
1044 )
1045 ,(MPARAM)0
1046 )
1047 );
1048 int nPixelRange = SHORT1FROMMR(::WinSendMsg( GetHwnd()
1049 ,SLM_QUERYSLIDERINFO
1050 ,MPFROM2SHORT( SMA_SHAFTDIMENSIONS
1051 ,SMA_RANGEVALUE
1052 )
1053 ,(MPARAM)0
1054 )
1055 );
1056 m_dPixelToRange = (double)(nPixelRange - m_nThumbLength)/(double)(m_nRangeMax - m_nRangeMin);
1057 int nNewPos = (int)(nValue * m_dPixelToRange);
1058
1059 ::WinSendMsg( GetHwnd()
1060 ,SLM_SETSLIDERINFO
1061 ,MPFROM2SHORT( SMA_SLIDERARMPOSITION
1062 ,SMA_RANGEVALUE
1063 )
1064 ,(MPARAM)nNewPos
1065 );
1066 if (m_hStaticValue)
1067 {
1068 wxSprintf(wxBuffer, wxT("%d"), nValue);
1069 ::WinSetWindowText((HWND)m_hStaticValue, wxBuffer);
1070 }
1071 } // end of wxSlider::SetValue
1072
1073 bool wxSlider::Show(
1074 bool bShow
1075 )
1076 {
1077 wxWindowOS2::Show(bShow);
1078 if(m_hStaticValue)
1079 ::WinShowWindow((HWND)m_hStaticValue, bShow);
1080 if(m_hStaticMin)
1081 ::WinShowWindow((HWND)m_hStaticMin, bShow);
1082 if(m_hStaticMax)
1083 ::WinShowWindow((HWND)m_hStaticMax, bShow);
1084 return TRUE;
1085 } // end of wxSlider::Show
1086