Develop and Download Open Source Software

Browse CVS Repository

Contents of /satellite/neuromanager/neuromanager/DataView.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (show annotations) (download) (as text)
Sat Feb 4 13:38:16 2006 UTC (18 years, 2 months ago) by orrisroot
Branch: MAIN
CVS Tags: HEAD
File MIME type: text/x-c++src
moved main application sources to neuromanager directory.

1 /* --------------------------------------------------------------------- */
2 /* NeuroManager - A spike train analysis tool */
3 /* Copyright (c) 2005-2006 RIKEN, Japan. All rights reserved. */
4 /* http://satellite.sourceforge.jp/ */
5 /* --------------------------------------------------------------------- */
6 /* This program is free software; you can redistribute it and/or */
7 /* modify it under the terms of the GNU General Public License */
8 /* as published by the Free Software Foundation; either version 2 */
9 /* of the License, or (at your option) any later version. */
10 /* */
11 /* This program is distributed in the hope that it will be useful, */
12 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
13 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
14 /* GNU General Public License for more details. */
15 /* */
16 /* You should have received a copy of the GNU General Public License */
17 /* along with this program; see the file COPYING.txt. If not, write */
18 /* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth */
19 /* Floor, Boston, MA 02110-1301, USA. */
20 /* --------------------------------------------------------------------- */
21
22 /* $Id: DataView.cpp,v 1.45 2006/01/24 01:59:57 orrisroot Exp $ */
23
24 // DataView.cpp : implementation of the CDataView class
25 //
26
27 #include "stdafx.h"
28 #include "NeuroManager.h"
29
30 #include "NeuroManagerDoc.h"
31
32 // #include "backup\MessageToString.h"
33
34 #include "DataViewSplitter.h"
35 #include "DataViewContext.h"
36 #include "DataViewProperties.h"
37 #include "DataView.h"
38 #include ".\dataview.h"
39
40 #include <math.h>
41
42 #ifdef _DEBUG
43 #define new DEBUG_NEW
44 #endif
45
46 // CDataView
47
48 IMPLEMENT_DYNCREATE( CDataView, CScrollView )
49
50 #define DATAVIEW_MUTEX "CDataView_Mutex"
51
52 #define MAX_SCROLLBAR_SIZE 32768 // range : 0~32767
53
54 #define DEFAULT_MAGNIFICATION pow(2.0, -3);
55 #define MAX_MAGNIFICATION pow(2.0,10) // 2^10
56 #define MIN_MAGNIFICATION pow(2.0,-10) // 2^-10
57
58 // CDataView construction/destruction
59 CDataView::CDataView()
60 {
61 // create mutex
62 m_pMutex = new CMutex( FALSE, DATAVIEW_MUTEX );
63
64 // constant value
65 m_uixPad = 20;
66 m_uiyPad = 20;
67
68 SetScrollSizes( MM_TEXT, CSize( 0, 0 ) );
69 m_rectClient.SetRect( 0, 0, 0, 0 );
70 m_pointMousePress.SetPoint( -1, -1 );
71
72 // parameter of view
73 m_dMagnification = DEFAULT_MAGNIFICATION;
74 m_qwLogicalXSize = 0; // horizontal scrollbar size
75 m_qwPhysicalXSize = 0; // data length * mag + xpad * 2
76 m_qwPhysicalXPos = 0; // left edge of data position
77 m_dPhysicalParLogicalXSize = 1.0;
78
79 m_cursorDrag = AfxGetApp() ->LoadStandardCursor( IDC_SIZEALL );
80
81 // create brush and pen
82 m_colorBackground = RGB( 0, 0, 0 );
83 m_colorForeground = RGB( 255, 255, 255 );
84 m_colorAxis = RGB( 127, 127, 127 );
85 m_brushBackground.CreateSolidBrush( m_colorBackground );
86 m_penForeground.CreatePen( PS_SOLID, 1, m_colorForeground );
87 m_penBackground.CreatePen( PS_SOLID, 1, m_colorBackground );
88 m_penAxis.CreatePen( PS_SOLID, 1, m_colorAxis );
89 }
90
91 CDataView::~CDataView()
92 {
93 m_brushBackground.DeleteObject();
94 delete m_pMutex;
95 }
96
97
98 BEGIN_MESSAGE_MAP( CDataView, CScrollView )
99 ON_WM_SIZE()
100 ON_WM_GETDLGCODE()
101 ON_WM_KEYDOWN()
102 ON_WM_LBUTTONDOWN()
103 ON_WM_LBUTTONUP()
104 ON_WM_MOUSEMOVE()
105 ON_WM_HSCROLL()
106 ON_WM_MBUTTONDOWN()
107 ON_WM_ERASEBKGND()
108 END_MESSAGE_MAP()
109
110
111 // CDataView drawing
112 void CDataView::OnDraw( CDC* pDC )
113 {
114 CNeuroManagerDoc * pDoc = ( CNeuroManagerDoc* ) GetDocument();
115 // TODO: add draw code for native data here
116 if ( pDoc )
117 {
118 // lock mutex
119 m_pMutex->Lock();
120 CRect rcClip;
121 pDC->GetClipBox( rcClip );
122 CRect rcBitmap = m_rectClient;
123 pDC->DPtoLP( rcBitmap );
124 CSize siz = rcBitmap.Size();
125 CSize offset( rcBitmap.left, rcBitmap.top );
126 rcBitmap.MoveToXY( 0, 0 );
127
128 if ( m_bitmapBuffer.m_hObject && m_bResizeRequired )
129 {
130 m_bitmapBuffer.DeleteObject();
131 m_memDC.DeleteDC();
132 }
133 if ( m_bitmapBuffer.m_hObject == NULL )
134 {
135 m_bitmapBuffer.CreateCompatibleBitmap( pDC, rcBitmap.Width(), rcBitmap.Height() );
136 m_memDC.CreateCompatibleDC( pDC );
137 m_memDC.SelectObject( m_bitmapBuffer );
138 m_bResizeRequired = FALSE;
139 m_bRedrawRequired = TRUE;
140 m_bUseScrollDraw = FALSE;
141 }
142 if ( m_bRedrawRequired )
143 {
144 CRgn rgn;
145 CRect rcBitmapClip = rcClip;
146 rcBitmapClip.MoveToXY( rcClip.left - offset.cx, rcClip.top - offset.cy );
147 if ( m_bUseScrollDraw && abs( m_iScrollDrawSize ) < rcBitmap.Width() )
148 {
149 ASSERT( m_iScrollDrawSize != 0 );
150 CRect rcNewClip;
151 m_memDC.ScrollDC( m_iScrollDrawSize, 0, rcBitmap, rcBitmapClip, NULL, &rcNewClip );
152 rcBitmapClip = rcNewClip;
153 }
154 rgn.CreateRectRgnIndirect( rcBitmapClip );
155 m_memDC.SelectClipRgn( &rgn );
156 Redraw( &m_memDC, &rcBitmap );
157 m_memDC.SelectClipRgn( NULL );
158 m_bRedrawRequired = FALSE;
159 m_bUseScrollDraw = FALSE;
160 }
161 pDC->SelectClipRgn( NULL );
162 pDC->BitBlt( rcClip.left, rcClip.top, rcClip.Width(), rcClip.Height(), &m_memDC,
163 rcClip.left - offset.cx, rcClip.top - offset.cy, SRCCOPY );
164 // unlock mutex
165 m_pMutex->Unlock();
166 }
167 }
168
169
170 // CDataView diagnostics
171
172 #ifdef _DEBUG
173 void CDataView::AssertValid() const
174 {
175 CScrollView::AssertValid();
176 }
177
178 void CDataView::Dump( CDumpContext& dc ) const
179 {
180 CScrollView::Dump( dc );
181 }
182 #endif //_DEBUG
183
184
185 // user defined methods
186 CFormView *CDataView::GetDataViewProperties()
187 {
188 CDataViewSplitter * wndSplit = ( CDataViewSplitter* ) GetParent();
189 if ( wndSplit == NULL )
190 return NULL;
191 CFormView *wndProp = wndSplit->GetDataViewPropertiesWindow();
192 return wndProp;
193 }
194
195 BOOL CDataView::GetPaintRect( CRect &rcClip, int iView, int iTargetView, CRect &rcResult )
196 {
197 CRect rcClient( m_rectClient );
198 CRect rcTemp1( m_rectClient );
199 int y_single = ( rcClient.Height() - ( int ) m_uiyPad ) / iView - ( int ) m_uiyPad;
200 int y_offset = ( y_single + ( int ) m_uiyPad ) * iTargetView + ( int ) m_uiyPad;
201 rcTemp1.top = y_offset;
202 rcTemp1.bottom = y_offset + y_single;
203
204 CRect rcTemp2;
205 BOOL bState = rcTemp2.IntersectRect( rcTemp1, rcClient );
206 if ( bState == FALSE )
207 return FALSE;
208 bState = rcTemp1.IntersectRect( rcClip, rcTemp2 );
209 if ( bState == FALSE )
210 return FALSE;
211 rcResult = rcTemp1;
212
213 return TRUE;
214 }
215
216 void CDataView::_paintBackground( CDC *pDC, CRect *pRectDest )
217 {
218 // set pen and brush style for backgournd painting
219 CBrush * oldbrush = pDC->SelectObject( &m_brushBackground );
220 CPen *oldpen = pDC->SelectObject( &m_penBackground );
221
222 CRect rcClip;
223 pDC->GetClipBox( rcClip );
224 pDC->Rectangle( rcClip );
225
226 // restore original pen and brush style
227 pDC->SelectObject( &oldbrush );
228 pDC->SelectObject( &oldpen );
229 }
230
231 void CDataView::_paintAxis( CDC *pDC, CRect *pRectDest, UINT nView, UINT nTargetView, double ymin, double ymax )
232 {
233 // set pen style for axis drawing
234 CPen * oldpen = pDC->SelectObject( &m_penAxis );
235
236 // initialize values
237 CSize siz = pRectDest->Size();
238 LONG xs, ys, xe, ye;
239
240 LONG y_single = ( siz.cy - m_uiyPad ) / nView - m_uiyPad;
241 LONG y_offset = ( y_single + m_uiyPad ) * nTargetView + m_uiyPad;
242 LONG y_zero = y_single * ymax / ( ymax - ymin );
243 LONG y_middle = y_offset + y_zero;
244
245 // vertical line of zero point
246 if ( m_qwPhysicalXPos <= m_uixPad )
247 {
248 xs = m_uixPad - m_qwPhysicalXPos + pRectDest->left;
249 ys = y_offset;
250 xe = xs;
251 ye = y_offset + y_single;
252 pDC->MoveTo( xs, ys );
253 pDC->LineTo( xe, ye );
254 }
255 // horizontal line of zero point
256 if ( 0 <= y_zero && y_zero <= y_single )
257 {
258 xs = pRectDest->left;
259 ys = y_middle;
260 if ( m_qwPhysicalXPos <= m_uixPad )
261 xs += m_uixPad - m_qwPhysicalXPos;
262 xe = pRectDest->right;
263 if ( m_qwPhysicalXPos + siz.cx > m_qwPhysicalXSize - m_uixPad )
264 xe -= m_qwPhysicalXPos + siz.cx - m_qwPhysicalXSize + m_uixPad;
265 ye = ys;
266 if ( xs < xe )
267 {
268 pDC->MoveTo( xs, ys );
269 pDC->LineTo( xe, ye );
270 }
271 }
272 // restore original pen style
273 pDC->SelectObject( &oldpen );
274 }
275
276 void CDataView::_paintData( CDC *pDC, CRect *pRectDest, UINT nView, UINT nTargetView, UINT nCh, double ymin, double ymax )
277 {
278 CNeuroManagerDoc * pDoc = ( CNeuroManagerDoc* ) GetDocument();
279 ASSERT_VALID( pDoc );
280
281 // set pen style for data drawing
282 CPen *oldpen = pDC->SelectObject( &m_penForeground );
283
284 // initialize values
285 CSize siz = pRectDest->Size();
286 LONG x, y;
287 CPoint ptDrawTo, ptDrawFrom;
288
289 LONG y_single = ( siz.cy - m_uiyPad ) / nView - m_uiyPad;
290 LONG y_offset = ( y_single + m_uiyPad ) * nTargetView + m_uiyPad;
291 LONG y_zero = y_single * ymax / ( ymax - ymin );
292 LONG y_middle = y_offset + y_zero;
293 double y_ratio = ( ( double ) y_single ) / ( ymax - ymin );
294
295 // get clipping box
296 CRect rcClip;
297 pDC->GetClipBox( rcClip );
298
299 // get data information
300 QWORD len = pDoc->GetDataLength();
301
302 // calculate range
303 QWORD i, ps, pe; // data pointer
304 int ls, le; // device position
305 ps = m_qwPhysicalXPos;
306 if ( m_qwPhysicalXPos < m_uixPad )
307 {
308 ps = 0;
309 ls = m_uixPad - m_qwPhysicalXPos;
310 }
311 else
312 {
313 QWORD ps2 = m_qwPhysicalXPos - m_uixPad;
314 ps = ps2 / m_dMagnification;
315 ls = -( ps2 - ps * m_dMagnification );
316 }
317 le = pRectDest->Width() - ls;
318 pe = ps + le / m_dMagnification + 1;
319 if ( pe > len )
320 pe = len - 1;
321 if ( ps < len && ps < pe )
322 {
323 // first data point
324 i = ps;
325 pDoc->AttachData( nCh );
326 x = pRectDest->left + ls;
327 while ( x < rcClip.left && i <= pe )
328 {
329 i++;
330 x = pRectDest->left + ls + ( i - ps ) * m_dMagnification;
331 }
332 if ( i != ps )
333 {
334 i--;
335 x = pRectDest->left + ls + ( i - ps ) * m_dMagnification;
336 }
337 double d = pDoc->GetData( i );
338 y = y_middle - ( int ) ( d * y_ratio );
339 ptDrawFrom.SetPoint( x, y );
340 i++;
341 LONG sy, maxy, miny, prex, prey;
342 BOOL bYCache = FALSE;
343 BOOL bContinue = TRUE;
344 for ( ; i <= pe && bContinue; i++ )
345 {
346 x = pRectDest->left + ls + ( i - ps ) * m_dMagnification;
347 if ( x > rcClip.right )
348 bContinue = FALSE;
349 d = pDoc->GetData( i );
350 y = y_middle - ( int ) ( d * y_ratio );
351 if ( ptDrawFrom.x == x )
352 {
353 if ( bYCache )
354 {
355 maxy = ( maxy > y ) ? maxy : y;
356 miny = ( miny < y ) ? miny : y;
357 prey = y;
358 }
359 else
360 {
361 prex = x;
362 sy = prey = y;
363 miny = maxy = y;
364 bYCache = TRUE;
365 }
366 }
367 else
368 {
369 if ( bYCache )
370 {
371 pDC->MoveTo( ptDrawFrom );
372 ptDrawTo.SetPoint( prex, sy );
373 pDC->LineTo( ptDrawTo );
374 ptDrawFrom.SetPoint( prex, maxy );
375 pDC->MoveTo( ptDrawFrom );
376 ptDrawTo.SetPoint( prex, miny );
377 pDC->LineTo( ptDrawTo );
378 ptDrawFrom.SetPoint( prex, prey );
379 bYCache = FALSE;
380 }
381 pDC->MoveTo( ptDrawFrom );
382 ptDrawTo.SetPoint( x, y );
383 ptDrawFrom.SetPoint( x, y );
384 pDC->LineTo( ptDrawTo );
385 }
386 }
387 pDoc->DetachData();
388 }
389
390 // restore original pen style
391 pDC->SelectObject( oldpen );
392 }
393
394 void CDataView::Redraw( CDC *pDC, CRect *pRectDest )
395 {
396 CDataViewProperties * wndProp = ( CDataViewProperties* ) GetDataViewProperties();
397 ASSERT_VALID( wndProp );
398
399 // paint background
400 _paintBackground( pDC, pRectDest );
401
402 UINT nView = wndProp->GetVisibleDataChannelSize();
403 if ( nView == 0 )
404 {
405 // paint axis only
406 _paintAxis( pDC, pRectDest, 1, 0, -1.0, 1.0 );
407 }
408 else
409 {
410 UINT nCh = 0;
411 double ymin, ymax;
412 CRect rcClipOrig, rcClipNew;
413 pDC->GetClipBox( rcClipOrig );
414 for ( UINT ii = 0; ii < nView; ii++ )
415 {
416 // seek to next visible channel
417 for ( ; wndProp->GetVisibleDataChannelState( nCh ) == FALSE; nCh++ )
418 ;
419 wndProp->GetDataYAxisRange( nCh, ymin, ymax );
420 BOOL bClip = GetPaintRect( rcClipOrig, ( int ) nView, ( int ) ii, rcClipNew );
421 if ( bClip )
422 {
423 CRgn rgn;
424 rgn.CreateRectRgnIndirect( rcClipNew );
425 pDC->SelectClipRgn( &rgn );
426 }
427 // paint axis
428 _paintAxis( pDC, pRectDest, nView, ii, ymin, ymax );
429 // paint data
430 _paintData( pDC, pRectDest, nView, ii, nCh, ymin, ymax );
431 if ( bClip )
432 {
433 CRgn rgn;
434 rgn.CreateRectRgnIndirect( rcClipOrig );
435 pDC->SelectClipRgn( &rgn );
436 }
437 nCh++;
438 }
439 }
440 }
441
442 QWORD CDataView::GetCurrentDataPos() const
443 {
444 CNeuroManagerDoc * pDoc = ( CNeuroManagerDoc* ) GetDocument();
445 ASSERT_VALID( pDoc );
446 QWORD pos = m_qwPhysicalXPos;
447 if ( !pDoc->IsMapped() )
448 return 0;
449 if ( m_qwPhysicalXPos < m_uixPad )
450 {
451 pos = 0;
452 }
453 else
454 {
455 QWORD tmp = m_qwPhysicalXPos - m_uixPad;
456 pos = tmp / m_dMagnification;
457 }
458 QWORD len = pDoc->GetDataLength();
459 if ( pos > len )
460 pos = len;
461 return pos;
462 }
463
464 void CDataView::UpdateScrollSizes( int cx, int cy )
465 {
466 CNeuroManagerDoc * pDoc = ( CNeuroManagerDoc* ) GetDocument();
467 ASSERT_VALID( pDoc );
468
469 CRect rcOld = m_rectClient;
470 m_rectClient.SetRect( 0, 0, cx, cy );
471
472 CSize sizeTotal = m_rectClient.Size();
473 if ( pDoc->IsMapped() )
474 {
475 m_qwPhysicalXSize = pDoc->GetDataLength() * m_dMagnification + m_uixPad * 2 - sizeTotal.cx;
476 if ( m_qwPhysicalXSize > MAX_SCROLLBAR_SIZE )
477 sizeTotal.cx = MAX_SCROLLBAR_SIZE;
478 else
479 sizeTotal.cx = m_qwPhysicalXSize;
480 }
481 else
482 {
483 m_qwPhysicalXSize = m_rectClient.Width();
484 }
485 m_qwLogicalXSize = sizeTotal.cx;
486 SetScrollSizes( MM_TEXT, sizeTotal );
487 // fix y size
488 CRect rcNew;
489 GetClientRect( rcNew );
490 if ( rcNew.bottom != sizeTotal.cy )
491 {
492 sizeTotal.cy = rcNew.bottom;
493 SetScrollSizes( MM_TEXT, sizeTotal );
494 m_rectClient.SetRect( 0, 0, cx, rcNew.bottom );
495 }
496
497 double dOld = m_dPhysicalParLogicalXSize;
498 BOOL bHasHorzBar, bHasVertBar;
499 CheckScrollBars( bHasHorzBar, bHasVertBar );
500 int limx = ( bHasHorzBar ) ? GetScrollLimit( SB_HORZ ) : sizeTotal.cx;
501 m_dPhysicalParLogicalXSize = ( double ) m_qwPhysicalXSize / ( double ) limx;
502
503 if ( rcOld != m_rectClient || dOld != m_dPhysicalParLogicalXSize )
504 {
505 m_bResizeRequired = TRUE;
506 }
507 }
508
509
510 void CDataView::DataViewHScrollBy( int nPos )
511 {
512 // check horizontal scroll bar available
513 BOOL bHasHorzBar, bHasVertBar;
514 CheckScrollBars( bHasHorzBar, bHasVertBar );
515 if ( bHasHorzBar == FALSE )
516 return ;
517
518 QWORD oldpx, newpx;
519 oldpx = newpx = m_qwPhysicalXPos;
520 // set new position of physical scroll bar and check range
521 if ( nPos > 0 )
522 {
523 if ( m_qwPhysicalXPos + nPos > m_qwPhysicalXSize )
524 newpx = m_qwPhysicalXSize;
525 else
526 newpx += nPos;
527 }
528 else
529 {
530 if ( m_qwPhysicalXPos < ( QWORD ) ( -nPos ) )
531 newpx = 0;
532 else
533 newpx += nPos;
534 }
535 int oldx = GetScrollPos( SB_HORZ );
536 int newx = newpx / m_dPhysicalParLogicalXSize;
537 // do scroll
538 if ( oldx != newx )
539 {
540 OnScrollBy( CSize( newx - oldx, 0 ), TRUE );
541 }
542 if ( oldpx != newpx )
543 {
544 // update scroll position
545 m_qwPhysicalXPos = newpx;
546 // update property panel
547 UpdatePropertiesTime();
548 // redraw
549 m_bRedrawRequired = TRUE;
550
551 INT64 diff = ( INT64 ) ( oldpx - newpx );
552 if ( diff < INT_MAX && diff > INT_MIN )
553 {
554 m_bUseScrollDraw = TRUE;
555 m_iScrollDrawSize = ( int ) diff;
556 }
557 else
558 {
559 m_bUseScrollDraw = FALSE;
560 }
561 Invalidate( FALSE );
562 UpdateWindow();
563 }
564 }
565
566 void CDataView::SetMagnification( double dMag )
567 {
568 if ( m_dMagnification == dMag )
569 return ;
570 if ( dMag > MAX_MAGNIFICATION || dMag < MIN_MAGNIFICATION )
571 {
572 ::MessageBeep( MB_OK );
573 }
574 else
575 {
576 QWORD oldpos = GetCurrentDataPos();
577 QWORD newpos = oldpos * dMag;
578 if ( m_qwPhysicalXPos > m_uixPad )
579 newpos += m_uixPad;
580 else
581 newpos += m_qwPhysicalXPos;
582 m_qwPhysicalXPos = newpos;
583 m_dMagnification = dMag;
584 UpdateScrollSizes( m_rectClient.Width(), m_rectClient.Height() );
585 int sbPos = m_qwPhysicalXPos / m_dPhysicalParLogicalXSize;
586 SetScrollPos( SB_HORZ, sbPos );
587 Invalidate( FALSE );
588
589 // buffered drawing
590 m_bRedrawRequired = TRUE;
591 m_bUseScrollDraw = FALSE;
592 }
593 }
594
595 void CDataView::UpdatePropertiesTime()
596 {
597 CNeuroManagerDoc * pDoc = ( CNeuroManagerDoc* ) GetDocument();
598 ASSERT_VALID( pDoc );
599 CDataViewProperties *wndProp = ( CDataViewProperties* ) GetDataViewProperties();
600 if ( wndProp == NULL )
601 return ;
602 double dTime = 0.0;
603 if ( pDoc->IsMapped() )
604 {
605 QWORD pos = GetCurrentDataPos();
606 dTime = pDoc->GetPosTime( pos );
607 wndProp->SetDataTime( dTime );
608 }
609 }
610
611
612 void CDataView::RedrawRequest()
613 {
614 // lock mutex
615 m_pMutex->Lock();
616
617 m_bRedrawRequired = TRUE;
618 m_bUseScrollDraw = FALSE;
619 Invalidate( FALSE );
620
621 // unlock mutex
622 m_pMutex->Unlock();
623 }
624
625 // CDataView message handlers
626
627 // protected methods
628 void CDataView::OnUpdate( CView* /*pSender*/, LPARAM /*lHint*/, CObject* /*pHint*/ )
629 {
630 CNeuroManagerDoc * pDoc = ( CNeuroManagerDoc* ) GetDocument();
631 ASSERT_VALID( pDoc );
632
633 // lock mutex
634 m_pMutex->Lock();
635
636 m_dMagnification = DEFAULT_MAGNIFICATION;
637 m_qwPhysicalXPos = 0;
638
639 CRect rect;
640 GetClientRect( rect );
641 UpdateScrollSizes( rect.Width(), rect.Height() );
642 SetScrollPos( SB_HORZ, 0, TRUE );
643
644 // buffered drawing
645 m_bRedrawRequired = TRUE;
646 m_bUseScrollDraw = FALSE;
647
648 // older versions of Windows* (NT 3.51 for instance)
649 // fail with DEFAULT_GUI_FONT
650 //if (!m_font.CreateStockObject(DEFAULT_GUI_FONT))
651 // if (!m_font.CreatePointFont(80, "MS Sans Serif"))
652 // return -1;
653
654 // unlock mutex
655 m_pMutex->Unlock();
656 }
657
658 BOOL CDataView::OnScrollBy( CSize sizeScroll, BOOL bDoScroll )
659 {
660 int xOrig, x;
661 int yOrig, y;
662
663 // lock mutex
664 m_pMutex->Lock();
665
666 // don't scroll if there is no valid scroll range (ie. no scroll bar)
667 CScrollBar* pBar;
668 DWORD dwStyle = GetStyle();
669
670 pBar = GetScrollBarCtrl( SB_VERT );
671 if ( ( pBar != NULL && !pBar->IsWindowEnabled() ) ||
672 ( pBar == NULL && !( dwStyle & WS_VSCROLL ) ) )
673 {
674 // vertical scroll bar not enabled
675 sizeScroll.cy = 0;
676 }
677 pBar = GetScrollBarCtrl( SB_HORZ );
678 if ( ( pBar != NULL && !pBar->IsWindowEnabled() ) ||
679 ( pBar == NULL && !( dwStyle & WS_HSCROLL ) ) )
680 {
681 // horizontal scroll bar not enabled
682 sizeScroll.cx = 0;
683 }
684
685 // adjust current x position
686 xOrig = x = GetScrollPos( SB_HORZ );
687 int xMax = GetScrollLimit( SB_HORZ );
688 x += sizeScroll.cx;
689 if ( x < 0 )
690 x = 0;
691 else if ( x > xMax )
692 x = xMax;
693
694 // adjust current y position
695 yOrig = y = GetScrollPos( SB_VERT );
696 int yMax = GetScrollLimit( SB_VERT );
697 y += sizeScroll.cy;
698 if ( y < 0 )
699 y = 0;
700 else if ( y > yMax )
701 y = yMax;
702
703 // did anything change?
704 if ( x == xOrig && y == yOrig )
705 return FALSE;
706
707 if ( bDoScroll )
708 {
709 // do scroll and update scroll positions
710 if ( x != xOrig )
711 SetScrollPos( SB_HORZ, x );
712 if ( y != yOrig )
713 SetScrollPos( SB_VERT, y );
714 }
715
716 // unlock mutex
717 m_pMutex->Unlock();
718
719 return TRUE;
720 }
721
722
723 // public methods
724
725 void CDataView::OnSize( UINT nType, int cx, int cy )
726 {
727 // lock mutex
728 m_pMutex->Lock();
729
730 CScrollView::OnSize( nType, cx, cy );
731 UpdateScrollSizes( cx, cy ); // for y range adjustment
732
733 // unlock mutex
734 m_pMutex->Unlock();
735 }
736
737
738 UINT CDataView::OnGetDlgCode()
739 {
740 // enable to input all key messages on control bar
741 return DLGC_WANTALLKEYS | CScrollView::OnGetDlgCode();
742 }
743
744 #define KEYSTATE_SHIFT_PRESSED() (GetKeyState(VK_LSHIFT)&0x8000||GetKeyState(VK_RSHIFT)&0x8000)
745
746 void CDataView::OnKeyDown( UINT nChar, UINT nRepCnt, UINT nFlags )
747 {
748 BOOL bHasHorzBar, bHasVertBar;
749 CheckScrollBars( bHasHorzBar, bHasVertBar );
750 if ( bHasHorzBar && ( nChar == VK_LEFT || nChar == VK_RIGHT ) )
751 {
752 // lock mutex
753 m_pMutex->Lock();
754
755 if ( ( GetKeyState( VK_CONTROL ) & 0x8000 ) && KEYSTATE_SHIFT_PRESSED() )
756 {
757 // control + shift + Left/Right
758 // change magnificant
759 double gain = ( nChar == VK_LEFT ) ? 0.5 : 2.0;
760 double newmag = gain * m_dMagnification;
761 SetMagnification( newmag );
762 }
763 else
764 {
765 static int nGain = 10;
766 static int nAccel = 5;
767 int gain = ( nChar == VK_LEFT ) ? -nGain : nGain;
768 // accellarate to scroll at shift key press with arrow keys
769 if ( KEYSTATE_SHIFT_PRESSED() )
770 gain *= nAccel;
771 DataViewHScrollBy( gain * nRepCnt );
772 }
773
774 // unlock mutex
775 m_pMutex->Unlock();
776 }
777 }
778
779
780 void CDataView::OnLButtonDown( UINT nFlags, CPoint point )
781 {
782 // set mouse pointer
783 BOOL bHasHorzBar, bHasVertBar;
784 CheckScrollBars( bHasHorzBar, bHasVertBar );
785 if ( bHasHorzBar )
786 {
787 m_pointMousePress = point;
788 ::SetCursor( m_cursorDrag );
789 }
790 else
791 {
792 m_pointMousePress.SetPoint( -1, -1 );
793 }
794 CScrollView::OnLButtonDown( nFlags, point );
795 }
796
797
798 void CDataView::OnLButtonUp( UINT nFlags, CPoint point )
799 {
800 // unset mouse pointer
801 m_pointMousePress.SetPoint( -1, -1 );
802 CScrollView::OnLButtonUp( nFlags, point );
803 }
804
805
806 void CDataView::OnMButtonDown( UINT nFlags, CPoint point )
807 {
808 // disable to scrolling using middle button. it doesn't works.
809 CWnd::OnMButtonDown( nFlags, point );
810 }
811
812
813 void CDataView::OnMouseMove( UINT nFlags, CPoint point )
814 {
815 BOOL bHasHorzBar, bHasVertBar;
816 CheckScrollBars( bHasHorzBar, bHasVertBar );
817 if ( bHasHorzBar && nFlags == MK_LBUTTON )
818 {
819 if ( m_pointMousePress.x != -1 )
820 {
821 // lock mutex
822 m_pMutex->Lock();
823
824 int pos = m_pointMousePress.x - point.x;
825 m_pointMousePress = point;
826 ::SetCursor( m_cursorDrag );
827 DataViewHScrollBy( pos );
828
829 // unlock mutex
830 m_pMutex->Lock();
831 }
832 }
833 CScrollView::OnMouseMove( nFlags, point );
834 }
835
836
837 void CDataView::OnHScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar )
838 {
839 int dx = 0;
840 static const int gainLine = 3;
841 static const int gainPage = 100;
842
843 // validate pScrollBar
844 if ( pScrollBar != NULL && pScrollBar->SendChildNotifyLastMsg() )
845 return ;
846 if ( pScrollBar != GetScrollBarCtrl( SB_HORZ ) )
847 return ;
848
849 // lock mutex
850 m_pMutex->Lock();
851 switch ( nSBCode )
852 {
853 case SB_LINELEFT:
854 // scroll one line to left
855 dx = -gainLine;
856 break;
857 case SB_LINERIGHT:
858 // scroll one line to right
859 dx = gainLine;
860 break;
861 case SB_PAGELEFT:
862 // scroll one page to left
863 dx = -gainPage;
864 break;
865 case SB_PAGERIGHT:
866 // scroll one page to right
867 dx = gainPage;
868 break;
869 case SB_THUMBTRACK:
870 // scroll to nPos
871 if ( m_dMagnification <= pow( 2.0, -9 ) )
872 break;
873 case SB_THUMBPOSITION:
874 // check needs to change logical scroll bar position
875 if ( GetScrollPos( SB_HORZ ) != nPos )
876 dx = ( int ) ( ( INT64 ) ( nPos * m_dPhysicalParLogicalXSize ) - ( INT64 ) m_qwPhysicalXPos );
877 break;
878 default:
879 break;
880 }
881 DataViewHScrollBy( dx );
882
883 // unlock mutex
884 m_pMutex->Unlock();
885 }
886
887 BOOL CDataView::OnEraseBkgnd( CDC* pDC )
888 {
889 return TRUE; // disable to erase background
890 }
891
892 //BOOL CDataView::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
893 //{
894 // CWindowsMessageToString msgConverter;
895 // LPSTR lpszMsg = msgConverter.GetStringFromMsg( message );
896 // if( message != 867 && message != 132) {
897 // TRACE("message ID[%d] : %s\n", message, lpszMsg);
898 // }
899 // return CScrollView::OnWndMsg(message, wParam, lParam, pResult);
900 //}

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26