]>
Commit | Line | Data |
---|---|---|
bd9396d5 HH |
1 | ///////////////////////////////////////////////////////////////////////////// |
2 | // Name: No names yet. | |
3 | // Purpose: Contrib. demo | |
4 | // Author: Aleksandras Gluchovas | |
5 | // Modified by: | |
6 | // Created: 06/10/98 | |
7 | // RCS-ID: $Id$ | |
8 | // Copyright: (c) Aleksandras Gluchovas | |
9 | // Licence: wxWindows license | |
10 | ///////////////////////////////////////////////////////////////////////////// | |
11 | ||
12 | #ifdef __GNUG__ | |
13 | #pragma implementation "rowdragpl.h" | |
14 | // #pragma interface | |
15 | #endif | |
16 | ||
17 | // For compilers that support precompilation, includes "wx.h". | |
18 | #include "wx/wxprec.h" | |
19 | ||
20 | #ifdef __BORLANDC__ | |
21 | #pragma hdrstop | |
22 | #endif | |
23 | ||
24 | #ifndef WX_PRECOMP | |
25 | #include "wx/wx.h" | |
26 | #endif | |
27 | ||
28 | #include "rowdragpl.h" | |
29 | ||
30 | #define MINIMAL_ROW_DRAG_OFS 5 | |
31 | ||
32 | // parameters for row-hints of NC-look | |
33 | ||
34 | #define TRIANGLE_OFFSET 2 | |
35 | #define TRIANGLE_TO_PAT_GAP 2 | |
36 | #define PAT_OFFSET 2 | |
37 | #define COLLAPSED_ICON_WIDTH 45 | |
38 | #define COLLAPSED_ICON_HEIGHT 9 | |
39 | #define ROW_DRAG_HINT_WIDTH 10 | |
40 | #define ICON_TRIAN_WIDTH 6 | |
41 | #define ICON_TRIAN_HEIGHT 3 | |
42 | ||
43 | /***** Implementaiton for class cbHiddenBarInfo *****/ | |
44 | ||
45 | IMPLEMENT_DYNAMIC_CLASS( cbHiddenBarInfo, wxObject ) | |
46 | ||
47 | /***** Implementaiton for class cbRowDragPlugin *****/ | |
48 | ||
49 | IMPLEMENT_DYNAMIC_CLASS( cbRowDragPlugin, cbPluginBase ) | |
50 | ||
51 | BEGIN_EVENT_TABLE( cbRowDragPlugin, cbPluginBase ) | |
52 | ||
53 | EVT_PL_LEFT_DOWN ( cbRowDragPlugin::OnLButtonDown ) | |
54 | EVT_PL_LEFT_UP ( cbRowDragPlugin::OnLButtonUp ) | |
55 | EVT_PL_MOTION ( cbRowDragPlugin::OnMouseMove ) | |
56 | ||
57 | EVT_PL_DRAW_PANE_DECOR ( cbRowDragPlugin::OnDrawPaneBackground ) | |
58 | ||
59 | END_EVENT_TABLE() | |
60 | ||
61 | // FIXME:: how to eliminated these cut&pasted constructors? | |
62 | ||
63 | cbRowDragPlugin::cbRowDragPlugin(void) | |
64 | ||
65 | : mDragStarted ( FALSE ), | |
66 | mDecisionMode ( FALSE ), | |
67 | mCurDragOfs ( 0 ), | |
68 | mpPaneImage ( NULL ), | |
69 | mpRowImage ( NULL ), | |
70 | mpCombinedImage ( NULL ), | |
71 | ||
72 | mpRowInFocus ( NULL ), | |
73 | mCollapsedIconInFocus( -1 ), | |
74 | ||
75 | mCaptureIsOn ( FALSE ), | |
76 | ||
77 | mTrianInnerColor ( 0,0,255 ), | |
78 | mHightColor ( 192, 192, 255 ), | |
79 | mLowColor ( 192, 192, 192 ), | |
80 | mTrianInnerPen ( mTrianInnerColor, 1, wxSOLID ), | |
81 | ||
82 | mSvTopMargin ( -1 ), | |
83 | mSvBottomMargin ( -1 ), | |
84 | mSvLeftMargin ( -1 ), | |
85 | mSvRightMargin ( -1 ), | |
86 | mpPane ( NULL ) | |
87 | { | |
88 | } | |
89 | ||
90 | cbRowDragPlugin::cbRowDragPlugin( wxFrameLayout* pLayout, int paneMask ) | |
91 | ||
92 | : cbPluginBase( pLayout, paneMask ), | |
93 | ||
94 | mDragStarted ( FALSE ), | |
95 | mDecisionMode ( FALSE ), | |
96 | mCurDragOfs ( 0 ), | |
97 | mpPaneImage ( NULL ), | |
98 | mpRowImage ( NULL ), | |
99 | mpCombinedImage ( NULL ), | |
100 | ||
101 | mpRowInFocus ( NULL ), | |
102 | mCollapsedIconInFocus( -1 ), | |
103 | ||
104 | mCaptureIsOn ( FALSE ), | |
105 | ||
106 | mTrianInnerColor ( 0,0,255 ), | |
107 | mHightColor ( 192, 192, 255 ), | |
108 | mLowColor ( 192, 192, 192 ), | |
109 | mTrianInnerPen ( mTrianInnerColor, 1, wxSOLID ), | |
110 | ||
111 | mSvTopMargin ( -1 ), | |
112 | mSvBottomMargin ( -1 ), | |
113 | mSvLeftMargin ( -1 ), | |
114 | mSvRightMargin ( -1 ), | |
115 | mpPane ( NULL ) | |
116 | { | |
117 | } | |
118 | ||
119 | cbRowDragPlugin::~cbRowDragPlugin() | |
120 | { | |
121 | } | |
122 | ||
123 | // handlers for plugin events | |
124 | void cbRowDragPlugin::OnMouseMove( cbMotionEvent& event ) | |
125 | { | |
126 | // short-cuts | |
127 | wxPoint pos = event.mPos; | |
128 | mpPane = event.mpPane; | |
129 | ||
130 | mpPane->PaneToFrame( &pos.x, &pos.y ); | |
131 | ||
132 | if ( !mDragStarted ) | |
133 | { | |
134 | if ( mDecisionMode && mpRowInFocus ) | |
135 | { | |
136 | int ofs; | |
137 | ||
138 | if ( mpPane->IsHorizontal() ) | |
139 | ||
140 | ofs = pos.y - mDragOrigin.y; | |
141 | else | |
142 | ofs = pos.x - mDragOrigin.x; | |
143 | ||
144 | // check if the item was dragged sufficeintly | |
145 | // far, enough to consider that user really intends | |
146 | // to drag it | |
147 | ||
148 | if ( ofs >= MINIMAL_ROW_DRAG_OFS || | |
149 | ofs <= -MINIMAL_ROW_DRAG_OFS ) | |
150 | { | |
151 | // DBG:: | |
152 | //.wxPoint pos = event.mPos; | |
153 | //wxPoint drg = mDragOrigin; | |
154 | //int dif = event.mPos.x - mDragOrigin.x; | |
155 | ||
156 | mDragStarted = TRUE; | |
157 | mDecisionMode = FALSE; | |
158 | mDragOrigin = pos; | |
159 | ||
160 | PrepareForRowDrag(); | |
161 | return; | |
162 | } | |
163 | ||
164 | // this plugin "eats" all mouse input while item is dragged, | |
165 | return; | |
166 | } | |
167 | ||
168 | cbRowInfo* pRow = GetFirstRow(); | |
169 | ||
170 | bool focusFound = FALSE; | |
171 | ||
172 | while( pRow ) | |
173 | { | |
174 | if ( HitTestRowDragHint( pRow, pos ) ) | |
175 | { | |
176 | CheckPrevItemInFocus( pRow, -1 ); | |
177 | SetMouseCapture( TRUE ); | |
178 | ||
179 | focusFound = TRUE; | |
180 | ||
181 | mpRowInFocus = pRow; | |
182 | mCollapsedIconInFocus = -1; | |
183 | break; | |
184 | } | |
185 | ||
186 | pRow = pRow->mpNext; | |
187 | } | |
188 | ||
189 | if ( !focusFound ) | |
190 | { | |
191 | int hrCnt = GetHRowsCountForPane( event.mpPane ); | |
192 | ||
193 | for( int i = 0; i != hrCnt; ++i ) | |
194 | { | |
195 | if ( HitTestCollapsedRowIcon( i, pos ) ) | |
196 | { | |
197 | CheckPrevItemInFocus( NULL, i ); | |
198 | SetMouseCapture( TRUE ); | |
199 | ||
200 | focusFound = TRUE; | |
201 | ||
202 | mCollapsedIconInFocus = i; | |
203 | mpRowInFocus = NULL; | |
204 | break; | |
205 | } | |
206 | } | |
207 | } | |
208 | ||
209 | if ( !focusFound && ItemIsInFocus() ) | |
210 | { | |
211 | // kill focus from item previousely been in focus | |
212 | UnhiglightItemInFocus(); | |
213 | ||
214 | mpRowInFocus = NULL; | |
215 | mCollapsedIconInFocus = -1; | |
216 | SetMouseCapture( FALSE ); | |
217 | } | |
218 | ||
219 | if ( !ItemIsInFocus() ) | |
220 | ||
221 | // delegate it to other plugins | |
222 | event.Skip(); | |
223 | } | |
224 | else | |
225 | { | |
226 | // otherwise mouse pointer moves, when dragging is started | |
227 | ||
228 | if ( mpPane->IsHorizontal() ) | |
229 | { | |
230 | // DBG:: | |
231 | wxPoint p = event.mPos; | |
232 | wxPoint d = mDragOrigin; | |
233 | int dif = event.mPos.x - mDragOrigin.x; | |
234 | ||
235 | // row is dragged up or down; | |
236 | ShowDraggedRow( pos.y - mDragOrigin.y ); | |
237 | } | |
238 | else | |
239 | { | |
240 | // DBG:: | |
241 | wxPoint p = event.mPos; | |
242 | wxPoint d = mDragOrigin; | |
243 | int dif = event.mPos.x - mDragOrigin.x; | |
244 | ||
245 | // row is dragged left or right | |
246 | ShowDraggedRow( pos.x - mDragOrigin.x ); | |
247 | } | |
248 | ||
249 | // this plugin "eats" all mouse input while item is dragged, | |
250 | } | |
251 | } | |
252 | ||
253 | void cbRowDragPlugin::OnLButtonDown( cbLeftDownEvent& event ) | |
254 | { | |
255 | mpPane = event.mpPane; | |
256 | ||
257 | // DBG:: | |
258 | wxASSERT( !mDragStarted && !mDecisionMode ); | |
259 | ||
260 | if ( ItemIsInFocus() ) | |
261 | { | |
262 | mDecisionMode = TRUE; | |
263 | ||
264 | wxPoint pos = event.mPos; | |
265 | mpPane->PaneToFrame( &pos.x, &pos.y ); | |
266 | ||
267 | mDragOrigin = pos; | |
268 | ||
269 | SetMouseCapture( TRUE ); | |
270 | } | |
271 | else | |
272 | // propagate event to other plugins | |
273 | event.Skip(); | |
274 | } | |
275 | ||
276 | void cbRowDragPlugin::OnLButtonUp ( cbLeftUpEvent& event ) | |
277 | { | |
278 | if ( !mDragStarted && !mDecisionMode ) | |
279 | { | |
280 | event.Skip(); | |
281 | return; | |
282 | } | |
283 | ||
284 | mpPane = event.mpPane; | |
285 | ||
286 | if ( mDecisionMode ) | |
287 | { | |
288 | cbDockPane* pPane = mpPane; | |
289 | ||
290 | SetMouseCapture( FALSE ); | |
291 | ||
292 | mDecisionMode = FALSE; | |
293 | mDragStarted = FALSE; | |
294 | ||
295 | wxPoint frmPos = event.mPos; | |
296 | pPane->PaneToFrame( &frmPos.x, &frmPos.y ); | |
297 | ||
298 | if ( mpRowInFocus ) | |
299 | { | |
300 | CollapseRow( mpRowInFocus ); | |
301 | mpRowInFocus = 0; | |
302 | } | |
303 | else | |
304 | { | |
305 | ExpandRow( mCollapsedIconInFocus ); | |
306 | mCollapsedIconInFocus = -1; | |
307 | } | |
308 | ||
309 | mpRowInFocus = NULL; | |
310 | mpPane = pPane; | |
311 | ||
312 | pPane->FrameToPane( &frmPos.x, &frmPos.y ); | |
313 | ||
314 | // give it another try after relayouting bars | |
315 | ||
316 | cbMotionEvent moveEvt( frmPos, pPane ); | |
317 | this->OnMouseMove( moveEvt ); | |
318 | ||
319 | // this plugin has "eaten" the mouse-up event | |
320 | ||
321 | return; | |
322 | } | |
323 | else | |
324 | { | |
325 | // otherwise, the dragged row was dropped, determine | |
326 | // where to insert it | |
327 | ||
328 | // restore initial pane appearence | |
329 | ShowPaneImage(); | |
330 | FinishOnScreenDraw(); | |
331 | ||
332 | cbRowInfo* pRow = GetFirstRow(); | |
333 | ||
334 | mpLayout->GetUpdatesManager().OnStartChanges(); | |
335 | ||
336 | pRow->mUMgrData.SetDirty(TRUE); | |
337 | ||
338 | cbBarInfo* pBar = mpRowInFocus->mBars[0]; | |
339 | ||
340 | while ( pBar ) | |
341 | { | |
342 | pBar->mUMgrData.SetDirty(TRUE); | |
343 | ||
344 | if ( pBar->mpBarWnd ) | |
345 | { | |
346 | // do complete refresh | |
347 | pBar->mpBarWnd->Show(FALSE); | |
348 | pBar->mpBarWnd->Show(TRUE); | |
349 | } | |
350 | ||
351 | pBar = pBar->mpNext; | |
352 | } | |
353 | ||
354 | while( pRow ) | |
355 | { | |
356 | if ( mCurDragOfs < pRow->mRowY ) | |
357 | { | |
358 | InsertDraggedRowBefore( pRow ); | |
359 | break; | |
360 | } | |
361 | ||
362 | pRow = pRow->mpNext; | |
363 | } | |
364 | ||
365 | if ( pRow == NULL ) InsertDraggedRowBefore( NULL ); | |
366 | ||
367 | mpRowInFocus = NULL; | |
368 | ||
369 | mpLayout->RecalcLayout(FALSE); | |
370 | ||
371 | // finish change "transaction" | |
372 | mpLayout->GetUpdatesManager().OnFinishChanges(); | |
373 | mpLayout->GetUpdatesManager().UpdateNow(); | |
374 | ||
375 | // finish drag action | |
376 | SetMouseCapture( FALSE ); | |
377 | mDragStarted = FALSE; | |
378 | } | |
379 | } | |
380 | ||
381 | void cbRowDragPlugin::OnDrawPaneBackground ( cbDrawPaneDecorEvent& event ) | |
382 | { | |
383 | mpPane = event.mpPane; | |
384 | ||
385 | // FIXME:: this may harm operation of other plugins | |
386 | ||
387 | if ( GetNextHandler() && mpPane->GetRowList().GetCount() ) | |
388 | { | |
389 | // first, let other plugins add their decorations now | |
390 | ||
391 | GetNextHandler()->ProcessEvent( event ); | |
392 | event.Skip(FALSE); | |
393 | } | |
394 | ||
395 | wxClientDC dc( &mpLayout->GetParentFrame() ); | |
396 | ||
397 | dc.SetClippingRegion( mpPane->mBoundsInParent.x, | |
398 | mpPane->mBoundsInParent.y, | |
399 | mpPane->mBoundsInParent.width, | |
400 | mpPane->mBoundsInParent.height ); | |
401 | ||
402 | int cnt = GetHRowsCountForPane( event.mpPane ); | |
403 | ||
404 | if ( cnt > 0 ) | |
405 | ||
406 | DrawCollapsedRowsBorder( dc ); | |
407 | ||
408 | if ( mpPane->GetRowList().GetCount() ) | |
409 | ||
410 | DrawRowsDragHintsBorder( dc ); | |
411 | ||
412 | cbRowInfo* pRow = GetFirstRow(); | |
413 | ||
414 | while( pRow ) | |
415 | { | |
416 | DrawRowDragHint( pRow, dc, FALSE ); | |
417 | pRow = pRow->mpNext; | |
418 | } | |
419 | ||
420 | for( int i = 0; i != cnt; ++i ) | |
421 | ||
422 | DrawCollapsedRowIcon(i, dc, FALSE ); | |
423 | } | |
424 | ||
425 | int cbRowDragPlugin::GetHRowsCountForPane( cbDockPane* pPane ) | |
426 | { | |
427 | wxNode* pNode = mHiddenBars.First(); | |
428 | ||
429 | int maxIconNo = -1; | |
430 | ||
431 | while( pNode ) | |
432 | { | |
433 | cbHiddenBarInfo* pHBInfo = (cbHiddenBarInfo*)pNode->Data(); | |
434 | ||
435 | if ( pHBInfo->mAlignment == pPane->mAlignment ) | |
436 | ||
437 | maxIconNo = wxMax( maxIconNo, pHBInfo->mIconNo ); | |
438 | ||
439 | pNode = pNode->Next(); | |
440 | } | |
441 | ||
442 | return ( maxIconNo + 1 ); | |
443 | } | |
444 | ||
445 | int cbRowDragPlugin::GetCollapsedRowIconHeight() | |
446 | { | |
447 | return COLLAPSED_ICON_HEIGHT; | |
448 | } | |
449 | ||
450 | int cbRowDragPlugin::GetRowDragHintWidth() | |
451 | { | |
452 | return ROW_DRAG_HINT_WIDTH; | |
453 | } | |
454 | ||
455 | void cbRowDragPlugin::SetPaneMargins() | |
456 | { | |
457 | int hiddenRowsCnt = GetHRowsCountForPane( mpPane ); | |
458 | ||
459 | if ( mSvTopMargin == -1 ) | |
460 | { | |
461 | mSvTopMargin = mpPane->mTopMargin; | |
462 | mSvBottomMargin = mpPane->mBottomMargin; | |
463 | mSvLeftMargin = mpPane->mLeftMargin; | |
464 | mSvRightMargin = mpPane->mRightMargin; | |
465 | } | |
466 | ||
467 | if ( mpPane->IsHorizontal() ) | |
468 | { | |
469 | mpPane->mTopMargin = mSvTopMargin; | |
470 | mpPane->mBottomMargin = ( hiddenRowsCnt == 0 ) | |
471 | ? mSvBottomMargin | |
472 | : mSvBottomMargin + GetCollapsedRowIconHeight(); | |
473 | ||
474 | mpPane->mLeftMargin = mSvLeftMargin + GetRowDragHintWidth(); | |
475 | mpPane->mRightMargin = mSvRightMargin; | |
476 | } | |
477 | else | |
478 | { | |
479 | mpPane->mTopMargin = mSvTopMargin; | |
480 | mpPane->mBottomMargin = mSvBottomMargin + GetRowDragHintWidth(); | |
481 | ||
482 | mpPane->mLeftMargin = mSvLeftMargin; | |
483 | mpPane->mRightMargin = ( hiddenRowsCnt == 0 ) ? | |
484 | mSvRightMargin : mSvRightMargin + GetCollapsedRowIconHeight(); | |
485 | } | |
486 | } | |
487 | ||
488 | void cbRowDragPlugin::OnInitPlugin() | |
489 | { | |
490 | cbDockPane** panes = mpLayout->GetPanesArray(); | |
491 | ||
492 | for( int i = 0; i != MAX_PANES; ++i ) | |
493 | ||
494 | if ( panes[i]->MatchesMask( mPaneMask ) ) | |
495 | { | |
496 | mpPane = panes[i]; | |
497 | ||
498 | SetPaneMargins(); | |
499 | } | |
500 | } | |
501 | ||
502 | /*** helpers for drag&drop ***/ | |
503 | ||
504 | void cbRowDragPlugin::SetMouseCapture( bool captureOn ) | |
505 | { | |
506 | if ( mCaptureIsOn == captureOn ) return; | |
507 | ||
508 | if ( captureOn ) | |
509 | { | |
510 | mpLayout->CaptureEventsForPane( mpPane ); | |
511 | mpLayout->CaptureEventsForPlugin( this ); | |
512 | } | |
513 | else | |
514 | { | |
515 | mpLayout->ReleaseEventsFromPane( mpPane ); | |
516 | mpLayout->ReleaseEventsFromPlugin( this ); | |
517 | } | |
518 | ||
519 | mCaptureIsOn = captureOn; | |
520 | } | |
521 | ||
522 | void cbRowDragPlugin::UnhiglightItemInFocus() | |
523 | { | |
524 | wxClientDC dc( &mpLayout->GetParentFrame() ); | |
525 | ||
526 | if ( mpRowInFocus ) | |
527 | ||
528 | DrawRowDragHint( mpRowInFocus, dc, FALSE ); | |
529 | else | |
530 | if ( mCollapsedIconInFocus != - 1 ) | |
531 | ||
532 | DrawCollapsedRowIcon( mCollapsedIconInFocus, dc, FALSE ); | |
533 | } | |
534 | ||
535 | void cbRowDragPlugin::ShowDraggedRow( int offset ) | |
536 | { | |
537 | // create combined image of pane and dragged | |
538 | // row on it, in the mpCombinedImage bitmap | |
539 | ||
540 | if ( mpPane->IsHorizontal() ) | |
541 | { | |
542 | if ( mInitalRowOfs + offset + mRowImgDim.y > mCombRect.y + mCombRect.height ) | |
543 | ||
544 | offset = mCombRect.y + mCombRect.height - mRowImgDim.y - mInitalRowOfs; | |
545 | ||
546 | if ( mInitalRowOfs + offset < mCombRect.y ) | |
547 | ||
548 | offset = mCombRect.y - mInitalRowOfs; | |
549 | ||
550 | long x, y = mInitalRowOfs + offset; | |
551 | mpPane->FrameToPane( &x, &y ); | |
552 | mCurDragOfs = y; | |
553 | } | |
554 | else | |
555 | { | |
556 | if ( mInitalRowOfs + offset + mRowImgDim.x > mCombRect.x + mCombRect.width ) | |
557 | ||
558 | offset = mCombRect.x + mCombRect.width - mRowImgDim.x - mInitalRowOfs; | |
559 | ||
560 | if ( mInitalRowOfs + offset < mCombRect.x ) | |
561 | ||
562 | offset = mCombRect.x - mInitalRowOfs; | |
563 | ||
564 | long x = mInitalRowOfs + offset, y; | |
565 | mpPane->FrameToPane( &x, &y ); | |
566 | mCurDragOfs = x; | |
567 | } | |
568 | ||
569 | wxMemoryDC rowImgDc; | |
570 | rowImgDc.SelectObject ( *mpRowImage ); | |
571 | ||
572 | wxMemoryDC paneImgDc; | |
573 | paneImgDc.SelectObject( *mpPaneImage ); | |
574 | ||
575 | wxMemoryDC combImgDc; | |
576 | combImgDc.SelectObject( *mpCombinedImage ); | |
577 | ||
578 | combImgDc.Blit( 0,0, mCombRect.width, mCombRect.height, | |
579 | &paneImgDc, 0,0, wxCOPY ); | |
580 | ||
581 | if ( mpPane->IsHorizontal() ) | |
582 | { | |
583 | combImgDc.Blit( 0, mInitalRowOfs + offset - mCombRect.y, | |
584 | mCombRect.width, mRowImgDim.y, | |
585 | &rowImgDc, 0,0, wxCOPY ); | |
586 | } | |
587 | else | |
588 | { | |
589 | combImgDc.Blit( mInitalRowOfs + offset - mCombRect.x, | |
590 | 0, | |
591 | mRowImgDim.x, mCombRect.height, | |
592 | &rowImgDc, 0,0, wxCOPY ); | |
593 | } | |
594 | ||
595 | int scrX = mCombRect.x, | |
596 | scrY = mCombRect.y; | |
597 | ||
598 | mpLayout->GetParentFrame().ClientToScreen( &scrX, &scrY ); | |
599 | ||
600 | mpScrDc->Blit( scrX, scrY, mCombRect.width, mCombRect.height, | |
601 | &combImgDc, 0,0, wxCOPY ); | |
602 | ||
603 | rowImgDc .SelectObject( wxNullBitmap ); | |
604 | paneImgDc.SelectObject( wxNullBitmap ); | |
605 | combImgDc.SelectObject( wxNullBitmap ); | |
606 | } | |
607 | ||
608 | wxBitmap* cbRowDragPlugin::CaptureDCArea( wxDC& dc, wxRect& area ) | |
609 | { | |
610 | wxBitmap* pBmp = new wxBitmap( int(area.width), int(area.height) ); | |
611 | ||
612 | wxMemoryDC mdc; | |
613 | mdc.SelectObject( *pBmp ); | |
614 | ||
615 | mdc.Blit( 0,0, area.width, area.height, &dc, area.x, area.y, wxCOPY ); | |
616 | mdc.SelectObject( wxNullBitmap ); | |
617 | ||
618 | return pBmp; | |
619 | } | |
620 | ||
621 | void cbRowDragPlugin::PrepareForRowDrag() | |
622 | { | |
623 | wxRect rowBounds = mpRowInFocus->mBoundsInParent; | |
624 | ||
625 | if ( mpPane->IsHorizontal() ) | |
626 | { | |
627 | mCombRect = mpPane->mBoundsInParent; | |
628 | ||
629 | mCombRect.x += mpPane->mLeftMargin - ROW_DRAG_HINT_WIDTH - 1; | |
630 | mCombRect.y += mpPane->mTopMargin; | |
631 | ||
632 | mCombRect.width -= mpPane->mLeftMargin + mpPane->mRightMargin - ROW_DRAG_HINT_WIDTH - 1 - 1; | |
633 | mCombRect.height -= mpPane->mTopMargin + mpPane->mBottomMargin; | |
634 | ||
635 | mCombRect.height += 2*rowBounds.height; | |
636 | mCombRect.y -= rowBounds.height; | |
637 | mInitalRowOfs = rowBounds.y; | |
638 | ||
639 | rowBounds.y -= 1; | |
640 | rowBounds.height += 2; | |
641 | rowBounds.x = mCombRect.x; | |
642 | rowBounds.width = mCombRect.width; | |
643 | ||
644 | mRowImgDim.y = rowBounds.height; | |
645 | } | |
646 | else | |
647 | { | |
648 | mCombRect = mpPane->mBoundsInParent; | |
649 | ||
650 | mCombRect.y += mpPane->mTopMargin - 1; | |
651 | mCombRect.x += mpPane->mLeftMargin - 1; | |
652 | ; | |
653 | mCombRect.height -= mpPane->mTopMargin + mpPane->mBottomMargin - ROW_DRAG_HINT_WIDTH - 1 - 1; | |
654 | mCombRect.width -= mpPane->mLeftMargin + mpPane->mRightMargin; | |
655 | ||
656 | mCombRect.width += 2*rowBounds.width; | |
657 | mCombRect.x -= rowBounds.width; | |
658 | mInitalRowOfs = rowBounds.x; | |
659 | ||
660 | rowBounds.x -= 1; | |
661 | rowBounds.width += 2; | |
662 | rowBounds.y = mCombRect.y; | |
663 | rowBounds.height = mCombRect.height; | |
664 | ||
665 | mRowImgDim.x = rowBounds.width; | |
666 | } | |
667 | // output cobination results onto frame's client area | |
668 | wxScreenDC::StartDrawingOnTop(&mpLayout->GetParentFrame()); | |
669 | mpScrDc = new wxScreenDC(); | |
670 | ||
671 | int x = mCombRect.x, y = mCombRect.y; | |
672 | mpLayout->GetParentFrame().ClientToScreen( &x, &y ); | |
673 | ||
674 | wxRect scrRect = mCombRect; | |
675 | scrRect.x = x; | |
676 | scrRect.y = y; | |
677 | ||
678 | mpPaneImage = CaptureDCArea( *mpScrDc, scrRect ); | |
679 | ||
680 | wxMemoryDC mdc; | |
681 | mdc.SelectObject( *mpPaneImage ); | |
682 | mdc.SetDeviceOrigin( -mCombRect.x, -mCombRect.y ); | |
683 | ||
684 | DrawRectShade( rowBounds, mdc, -1, mpLayout->mGrayPen, mpLayout->mDarkPen ); | |
685 | DrawRectShade( rowBounds, mdc, 0, mpLayout->mLightPen, mpLayout->mBlackPen ); | |
686 | ||
687 | mpRowImage = CaptureDCArea( mdc, rowBounds ); | |
688 | ||
689 | // draw dark empty-row placeholder | |
690 | DrawEmptyRow( mdc, rowBounds ); | |
691 | ||
692 | //DrawRectShade( rowBounds, mdc, 0, mpLayout->mGrayPen, mpLayout->mDarkPen ); | |
693 | DrawRectShade( rowBounds, mdc, -1, mpLayout->mGrayPen, mpLayout->mGrayPen ); | |
694 | ||
695 | mdc.SelectObject( wxNullBitmap ); | |
696 | ||
697 | mpCombinedImage = new wxBitmap( int(mCombRect.width), int(mCombRect.height) ); | |
698 | ||
699 | // show it for the first time | |
700 | ShowDraggedRow( 0 ); | |
701 | } | |
702 | ||
703 | void cbRowDragPlugin::DrawEmptyRow( wxDC& dc, wxRect& rowBounds ) | |
704 | { | |
705 | wxBrush bkBrush( mpLayout->mDarkPen.GetColour(), wxSOLID ); | |
706 | ||
707 | // paint the "dark" empty-row placeholder | |
708 | ||
709 | dc.SetBrush( bkBrush ); | |
710 | dc.SetPen ( mpLayout->mNullPen ); | |
711 | ||
712 | dc.DrawRectangle( rowBounds.x, rowBounds.y, | |
713 | rowBounds.width+1, rowBounds.height+1 ); | |
714 | ||
715 | dc.SetBrush( wxNullBrush ); | |
716 | } | |
717 | ||
718 | void cbRowDragPlugin::ShowPaneImage() | |
719 | { | |
720 | int scrX = 0, scrY = 0; | |
721 | ||
722 | mpLayout->GetParentFrame().ClientToScreen( &scrX, &scrY ); | |
723 | ||
724 | wxMemoryDC mdc; | |
725 | mdc.SelectObject( *mpPaneImage ); | |
726 | ||
727 | mpScrDc->Blit( mCombRect.x + scrX, mCombRect.y + scrY, | |
728 | mCombRect.width, mCombRect.height, | |
729 | &mdc, 0,0, wxCOPY ); | |
730 | ||
731 | mdc.SelectObject( wxNullBitmap ); | |
732 | } | |
733 | ||
734 | void cbRowDragPlugin::FinishOnScreenDraw() | |
735 | { | |
736 | wxScreenDC::EndDrawingOnTop(); | |
737 | ||
738 | delete mpScrDc; | |
739 | delete mpCombinedImage; | |
740 | delete mpPaneImage; | |
741 | delete mpRowImage; | |
742 | ||
743 | mpScrDc = NULL; | |
744 | ||
745 | mpCombinedImage = mpPaneImage = mpRowImage = NULL; | |
746 | } | |
747 | ||
748 | void cbRowDragPlugin::CollapseRow( cbRowInfo* pRow ) | |
749 | { | |
750 | int iconCnt = GetHRowsCountForPane( mpPane ); | |
751 | ||
752 | mpLayout->GetUpdatesManager().OnStartChanges(); | |
753 | ||
754 | cbBarInfo* pBar = pRow->mBars[0]; | |
755 | ||
756 | int rowNo = 0; | |
757 | ||
758 | cbRowInfo* pCur = pRow; | |
759 | while( pCur->mpPrev ) { ++rowNo; pCur = pCur->mpPrev; } | |
760 | ||
761 | while( pBar ) | |
762 | { | |
763 | cbHiddenBarInfo* pHBInfo = new cbHiddenBarInfo(); | |
764 | ||
765 | pHBInfo->mpBar = pBar; | |
766 | pHBInfo->mRowNo = rowNo; | |
767 | pHBInfo->mIconNo = iconCnt; | |
768 | pHBInfo->mAlignment = mpPane->mAlignment; | |
769 | ||
770 | mHiddenBars.Append( (wxObject*) pHBInfo ); | |
771 | ||
772 | // hide it | |
773 | if ( pBar->mpBarWnd ) | |
774 | ||
775 | pBar->mpBarWnd->Show( FALSE ); | |
776 | ||
777 | pBar->mState = wxCBAR_HIDDEN; | |
778 | ||
779 | cbBarInfo* pNext = pBar->mpNext; | |
780 | ||
781 | pBar->mpRow = NULL; | |
782 | pBar->mpNext = NULL; | |
783 | pBar->mpPrev = NULL; | |
784 | ||
785 | pBar = pNext; | |
786 | } | |
787 | ||
788 | mpPane->GetRowList().Remove( pRow ); | |
789 | mpPane->InitLinksForRows(); | |
790 | ||
791 | delete pRow; | |
792 | ||
793 | SetPaneMargins(); | |
794 | ||
795 | mpLayout->RecalcLayout(FALSE); | |
796 | ||
797 | mpRowInFocus = NULL; | |
798 | ||
799 | mpLayout->GetUpdatesManager().OnFinishChanges(); | |
800 | mpLayout->GetUpdatesManager().UpdateNow(); | |
801 | } | |
802 | ||
803 | void cbRowDragPlugin::ExpandRow( int collapsedIconIdx ) | |
804 | { | |
805 | mpLayout->GetUpdatesManager().OnStartChanges(); | |
806 | ||
807 | cbRowInfo* pNewRow = new cbRowInfo(); | |
808 | ||
809 | wxNode* pNode = mHiddenBars.First(); | |
810 | ||
811 | int rowNo = 0; | |
812 | ||
813 | // move bars from internal list to the newly expanded row | |
814 | ||
815 | while( pNode ) | |
816 | { | |
817 | cbHiddenBarInfo* pHBInfo = (cbHiddenBarInfo*)pNode->Data(); | |
818 | ||
819 | if ( pHBInfo->mAlignment == mpPane->mAlignment && | |
820 | pHBInfo->mIconNo == collapsedIconIdx ) | |
821 | { | |
822 | rowNo = pHBInfo->mRowNo; | |
823 | ||
824 | if ( pHBInfo->mpBar->mState == wxCBAR_HIDDEN ) | |
825 | { | |
826 | pNewRow->mBars.Add( pHBInfo->mpBar ); | |
827 | ||
828 | pHBInfo->mpBar->mState = ( mpPane->IsHorizontal() ) | |
829 | ? wxCBAR_DOCKED_HORIZONTALLY | |
830 | : wxCBAR_DOCKED_VERTICALLY; | |
831 | } | |
832 | ||
833 | // remove bar info from internal list | |
834 | ||
835 | wxNode* pNext = pNode->Next(); | |
836 | ||
837 | delete pHBInfo; | |
838 | mHiddenBars.DeleteNode( pNode ); | |
839 | ||
840 | pNode = pNext; | |
841 | } | |
842 | else | |
843 | { | |
844 | // decrease incon numbers with higher indicies, since this | |
845 | // row is now removed from the hidden-rows list | |
846 | ||
847 | if ( pHBInfo->mIconNo > collapsedIconIdx && | |
848 | pHBInfo->mAlignment == mpPane->mAlignment ) | |
849 | ||
850 | --pHBInfo->mIconNo; | |
851 | ||
852 | pNode = pNode->Next(); | |
853 | } | |
854 | } | |
855 | ||
856 | mpPane->InitLinksForRow( pNewRow ); | |
857 | ||
858 | // insert row into pane at it's original position | |
859 | ||
860 | if ( pNewRow->mBars.GetCount() ) | |
861 | { | |
862 | cbRowInfo* beforeRowNode = mpPane->GetRow( rowNo ); | |
863 | ||
864 | mpPane->InsertRow( pNewRow, beforeRowNode ); | |
865 | } | |
866 | else | |
867 | delete pNewRow; | |
868 | ||
869 | SetPaneMargins(); | |
870 | ||
871 | mpLayout->RecalcLayout(FALSE); | |
872 | ||
873 | mCollapsedIconInFocus = -1; | |
874 | ||
875 | mpLayout->GetUpdatesManager().OnFinishChanges(); | |
876 | mpLayout->GetUpdatesManager().UpdateNow(); | |
877 | ||
878 | ||
879 | /* | |
880 | wxNode* pRowNode = mHiddenRows.Nth( collapsedIconIdx ); | |
881 | ||
882 | mpLayout->GetUpdatesManager().OnStartChanges(); | |
883 | ||
884 | // insert at the end of rows list | |
885 | mpPane->InsertRow( pRowNode, NULL ); | |
886 | ||
887 | int success = mHiddenRows.DeleteNode( pRowNode ); | |
888 | // DBG:: | |
889 | wxASSERT( success ); | |
890 | ||
891 | SetPaneMargins(); | |
892 | ||
893 | mpLayout->RecalcLayout(FALSE); | |
894 | ||
895 | mCollapsedIconInFocus = -1; | |
896 | ||
897 | mpLayout->GetUpdatesManager().OnFinishChanges(); | |
898 | mpLayout->GetUpdatesManager().UpdateNow(); | |
899 | */ | |
900 | } | |
901 | ||
902 | void cbRowDragPlugin::InsertDraggedRowBefore( cbRowInfo* pBeforeRow ) | |
903 | { | |
904 | if ( mpRowInFocus != pBeforeRow && | |
905 | mpRowInFocus->mpNext != pBeforeRow | |
906 | ) | |
907 | { | |
908 | mpPane->GetRowList().Remove( mpRowInFocus ); | |
909 | ||
910 | mpPane->InsertRow( mpRowInFocus, pBeforeRow ); | |
911 | } | |
912 | else | |
913 | { | |
914 | // otherwise, nothing has happned (row positions do not change) | |
915 | ||
916 | //wxClientDC dc( &mpLayout->GetParentFrame() ); | |
917 | ||
918 | //mpPane->PaintRow( mpRowInFocus, dc ); | |
919 | //DrawRowDragHint( mpRowInFocus, dc, FALSE ); | |
920 | } | |
921 | } | |
922 | ||
923 | bool cbRowDragPlugin::ItemIsInFocus() | |
924 | { | |
925 | return ( mpRowInFocus || mCollapsedIconInFocus != - 1 ); | |
926 | } | |
927 | ||
928 | void cbRowDragPlugin::CheckPrevItemInFocus( cbRowInfo* pRow, int iconIdx ) | |
929 | { | |
930 | wxClientDC dc( &mpLayout->GetParentFrame() ); | |
931 | ||
932 | if ( pRow != NULL && mpRowInFocus == pRow ) return; | |
933 | if ( iconIdx != -1 && mCollapsedIconInFocus == iconIdx ) return; | |
934 | ||
935 | UnhiglightItemInFocus(); | |
936 | ||
937 | if ( iconIdx != - 1 ) | |
938 | ||
939 | DrawCollapsedRowIcon( iconIdx, dc, TRUE ); | |
940 | ||
941 | else | |
942 | if ( pRow != NULL ) | |
943 | ||
944 | DrawRowDragHint( pRow, dc, TRUE ); | |
945 | } | |
946 | ||
947 | cbRowInfo* cbRowDragPlugin::GetFirstRow() | |
948 | { | |
949 | return ( mpPane->GetRowList().GetCount() ) | |
950 | ? mpPane->GetRowList()[0] | |
951 | : NULL; | |
952 | } | |
953 | ||
954 | /*** "hard-coded" metafile for NN-look ***/ | |
955 | ||
956 | void cbRowDragPlugin::DrawTrianUp( wxRect& inRect, wxDC& dc ) | |
957 | { | |
958 | int xOfs = (inRect.width - ICON_TRIAN_WIDTH)/2; | |
959 | ||
960 | wxBrush br( mTrianInnerColor, wxSOLID ); | |
961 | ||
962 | dc.SetBrush( br ); | |
963 | dc.SetPen( mpLayout->mBlackPen ); | |
964 | ||
965 | wxPoint points[3]; | |
966 | points[0].x = inRect.x + xOfs; | |
967 | points[0].y = inRect.y + inRect.height - 1; | |
968 | points[1].x = inRect.x + xOfs + ICON_TRIAN_WIDTH/2 + 1; | |
969 | points[1].y = inRect.y + inRect.height - 2 - ICON_TRIAN_HEIGHT; | |
970 | points[2].x = inRect.x + xOfs + ICON_TRIAN_WIDTH+1; | |
971 | points[2].y = inRect.y + inRect.height - 1; | |
972 | ||
973 | dc.DrawPolygon( 3, points ); | |
974 | ||
975 | // higlight upper-right edge of triangle | |
976 | dc.SetPen( mpLayout->mLightPen ); | |
977 | dc.DrawLine( points[2].x, points[2].y, | |
978 | points[0].x, points[0].y ); | |
979 | ||
980 | dc.SetBrush( wxNullBrush ); | |
981 | } | |
982 | ||
983 | void cbRowDragPlugin::DrawTrianDown( wxRect& inRect, wxDC& dc ) | |
984 | { | |
985 | int xOfs = (inRect.width - ICON_TRIAN_WIDTH)/2; | |
986 | ||
987 | wxBrush br( mTrianInnerColor, wxSOLID ); | |
988 | ||
989 | dc.SetBrush( br ); | |
990 | dc.SetPen( mpLayout->mBlackPen ); | |
991 | ||
992 | wxPoint points[3]; | |
993 | points[0].x = inRect.x + xOfs; | |
994 | points[0].y = inRect.y; | |
995 | points[1].x = inRect.x + xOfs + ICON_TRIAN_WIDTH; | |
996 | points[1].y = inRect.y; | |
997 | points[2].x = inRect.x + xOfs + ICON_TRIAN_WIDTH/2; | |
998 | points[2].y = inRect.y + ICON_TRIAN_HEIGHT; | |
999 | ||
1000 | dc.DrawPolygon( 3, points ); | |
1001 | ||
1002 | // higlight upper-right edge of triangle | |
1003 | dc.SetPen( mpLayout->mLightPen ); | |
1004 | dc.DrawLine( points[2].x, points[2].y, | |
1005 | points[1].x, points[1].y ); | |
1006 | ||
1007 | dc.SetBrush( wxNullBrush ); | |
1008 | } | |
1009 | ||
1010 | void cbRowDragPlugin::DrawTrianRight( wxRect& inRect, wxDC& dc ) | |
1011 | { | |
1012 | int yOfs = (inRect.height - ICON_TRIAN_WIDTH)/2; | |
1013 | ||
1014 | wxBrush br( mTrianInnerColor, wxSOLID ); | |
1015 | ||
1016 | dc.SetBrush( br ); | |
1017 | dc.SetPen( mpLayout->mBlackPen ); | |
1018 | ||
1019 | wxPoint points[3]; | |
1020 | points[0].x = inRect.x; | |
1021 | points[0].y = inRect.y + yOfs + ICON_TRIAN_WIDTH; | |
1022 | points[1].x = inRect.x; | |
1023 | points[1].y = inRect.y + yOfs; | |
1024 | points[2].x = inRect.x + ICON_TRIAN_HEIGHT; | |
1025 | points[2].y = inRect.y + yOfs + ICON_TRIAN_WIDTH/2; | |
1026 | ||
1027 | dc.DrawPolygon( 3, points ); | |
1028 | ||
1029 | // higlight upper-right edge of triangle | |
1030 | dc.SetPen( mpLayout->mLightPen ); | |
1031 | dc.DrawLine( points[0].x, points[0].y, | |
1032 | points[2].x, points[2].y ); | |
1033 | ||
1034 | dc.SetBrush( wxNullBrush ); | |
1035 | } | |
1036 | ||
1037 | void cbRowDragPlugin::Draw3DPattern( wxRect& inRect, wxDC& dc ) | |
1038 | { | |
1039 | for( int y = inRect.y; y < inRect.y + inRect.height; y+=3 ) | |
1040 | ||
1041 | for( int x = inRect.x; x < inRect.x + inRect.width; x+=3 ) | |
1042 | { | |
1043 | dc.SetPen( mpLayout->mLightPen ); | |
1044 | dc.DrawPoint( x,y ); | |
1045 | dc.SetPen( mpLayout->mBlackPen ); | |
1046 | dc.DrawPoint( x+1, y+1 ); | |
1047 | } | |
1048 | } | |
1049 | ||
1050 | void cbRowDragPlugin::DrawRombShades( wxPoint& p1, wxPoint& p2, | |
1051 | wxPoint& p3, wxPoint& p4, | |
1052 | wxDC& dc ) | |
1053 | { | |
1054 | dc.SetPen( mpLayout->mLightPen ); | |
1055 | dc.DrawLine( p1.x, p1.y, p2.x, p2.y ); | |
1056 | dc.DrawLine( p2.x, p2.y, p3.x, p3.y ); | |
1057 | dc.SetPen( mpLayout->mDarkPen ); | |
1058 | dc.DrawLine( p3.x, p3.y, p4.x, p4.y ); | |
1059 | dc.DrawLine( p4.x, p4.y, p1.x, p1.y ); | |
1060 | } | |
1061 | ||
1062 | void cbRowDragPlugin::DrawOrtoRomb( wxRect& inRect, wxDC& dc, wxBrush& bkBrush ) | |
1063 | { | |
1064 | dc.SetBrush( bkBrush ); | |
1065 | dc.SetPen( mpLayout->mBlackPen ); | |
1066 | ||
1067 | wxPoint points[4]; | |
1068 | ||
1069 | if ( inRect.width > inRect.height ) | |
1070 | { | |
1071 | // horizontal orienation | |
1072 | points[0].x = inRect.x; | |
1073 | points[0].y = inRect.y + inRect.height; | |
1074 | points[1].x = inRect.x; | |
1075 | points[1].y = inRect.y; | |
1076 | points[2].x = inRect.x + inRect.width; | |
1077 | points[2].y = inRect.y; | |
1078 | points[3].x = inRect.x + inRect.width - COLLAPSED_ICON_HEIGHT; | |
1079 | points[3].y = inRect.y + inRect.height; | |
1080 | ||
1081 | dc.DrawPolygon( 4, points ); | |
1082 | ||
1083 | // squeeze romb's bounds to create an inner-shade shape | |
1084 | ++points[0].x; | |
1085 | --points[0].y; | |
1086 | ++points[1].x; | |
1087 | ++points[1].y; | |
1088 | --points[2].x; --points[2].x; | |
1089 | ++points[2].y; | |
1090 | --points[3].y; | |
1091 | ||
1092 | DrawRombShades( points[0], points[1], points[2], points[3], dc ); | |
1093 | } | |
1094 | else | |
1095 | { | |
1096 | // vertical orientation | |
1097 | points[0].x = inRect.x + inRect.width; | |
1098 | points[0].y = inRect.y + inRect.height; | |
1099 | points[1].x = inRect.x; | |
1100 | points[1].y = inRect.y + inRect.height; | |
1101 | points[2].x = inRect.x; | |
1102 | points[2].y = inRect.y; | |
1103 | points[3].x = inRect.x + inRect.width; | |
1104 | points[3].y = inRect.y + COLLAPSED_ICON_HEIGHT; | |
1105 | ||
1106 | dc.DrawPolygon( 4, points ); | |
1107 | ||
1108 | // squeeze romb's bounds to create an inner-shade shape | |
1109 | --points[0].y ; | |
1110 | --points[0].x; | |
1111 | ++points[1].x; | |
1112 | --points[1].y; | |
1113 | ++points[2].y; ++points[2].y; | |
1114 | ++points[2].x; | |
1115 | --points[3].x; | |
1116 | ||
1117 | DrawRombShades( points[1], points[2], points[3], points[0], dc ); | |
1118 | } | |
1119 | ||
1120 | dc.SetBrush( wxNullBrush ); | |
1121 | } | |
1122 | ||
1123 | void cbRowDragPlugin::DrawRomb( wxRect& inRect, wxDC& dc, wxBrush& bkBrush ) | |
1124 | { | |
1125 | wxPoint points[4]; | |
1126 | ||
1127 | dc.SetBrush( bkBrush ); | |
1128 | dc.SetPen( mpLayout->mBlackPen ); | |
1129 | ||
1130 | if ( inRect.width > inRect.height ) | |
1131 | { | |
1132 | // horizontal orientation | |
1133 | points[0].x = inRect.x; | |
1134 | points[0].y = inRect.y + inRect.height; | |
1135 | points[1].x = inRect.x + COLLAPSED_ICON_HEIGHT; | |
1136 | points[1].y = inRect.y; | |
1137 | points[2].x = inRect.x + inRect.width; | |
1138 | points[2].y = inRect.y; | |
1139 | points[3].x = inRect.x + inRect.width - COLLAPSED_ICON_HEIGHT; | |
1140 | points[3].y = inRect.y + inRect.height; | |
1141 | ||
1142 | dc.DrawPolygon( 4, points ); | |
1143 | ||
1144 | // squeeze romb's bounds to create an inner-shade shape | |
1145 | ++points[0].x ;++points[0].x ; | |
1146 | --points[0].y; | |
1147 | ++points[1].y; | |
1148 | --points[2].x; --points[2].x; | |
1149 | ++points[2].y; | |
1150 | //--points[3].x ; | |
1151 | --points[3].y; | |
1152 | ||
1153 | DrawRombShades( points[0], points[1], points[2], points[3], dc ); | |
1154 | ||
1155 | } | |
1156 | else | |
1157 | { | |
1158 | // vertical orientation | |
1159 | points[0].x = inRect.x + inRect.width; | |
1160 | points[0].y = inRect.y + inRect.height; | |
1161 | points[1].x = inRect.x; | |
1162 | points[1].y = inRect.y + inRect.height - COLLAPSED_ICON_HEIGHT; | |
1163 | points[2].x = inRect.x; | |
1164 | points[2].y = inRect.y; | |
1165 | points[3].x = inRect.x + inRect.width; | |
1166 | points[3].y = inRect.y + COLLAPSED_ICON_HEIGHT; | |
1167 | ||
1168 | dc.DrawPolygon( 4, points ); | |
1169 | ||
1170 | // squeeze romb's bounds to create an inner-shade shape | |
1171 | --points[0].y ;--points[0].y ; | |
1172 | --points[0].x; | |
1173 | ++points[1].x; | |
1174 | ++points[2].y; ++points[2].y; | |
1175 | ++points[2].x; | |
1176 | --points[3].x; | |
1177 | ||
1178 | DrawRombShades( points[1], points[2], points[3], points[0], dc ); | |
1179 | } | |
1180 | ||
1181 | dc.SetBrush( wxNullBrush ); | |
1182 | } | |
1183 | ||
1184 | void cbRowDragPlugin::DrawRectShade( wxRect& inRect, wxDC& dc, | |
1185 | int level, wxPen& upperPen, wxPen& lowerPen ) | |
1186 | { | |
1187 | // upper shade | |
1188 | dc.SetPen( upperPen ); | |
1189 | dc.DrawLine( inRect.x - level, | |
1190 | inRect.y - level, | |
1191 | inRect.x + inRect.width - 1 + level, | |
1192 | inRect.y - level); | |
1193 | dc.DrawLine( inRect.x - level, inRect.y - level, | |
1194 | inRect.x - level, inRect.y + inRect.height - 1 + level ); | |
1195 | ||
1196 | // lower shade | |
1197 | dc.SetPen( lowerPen ); | |
1198 | dc.DrawLine( inRect.x - level, | |
1199 | inRect.y + inRect.height - 1 + level, | |
1200 | inRect.x + inRect.width + level, | |
1201 | inRect.y + inRect.height - 1 + level); | |
1202 | dc.DrawLine( inRect.x + inRect.width - 1 + level, | |
1203 | inRect.y - level, | |
1204 | inRect.x + inRect.width - 1 + level, | |
1205 | inRect.y + inRect.height + level); | |
1206 | ||
1207 | dc.SetBrush( wxNullBrush ); | |
1208 | } | |
1209 | ||
1210 | void cbRowDragPlugin::Draw3DRect( wxRect& inRect, wxDC& dc, wxBrush& bkBrush ) | |
1211 | { | |
1212 | dc.SetPen( mpLayout->mNullPen ); | |
1213 | dc.SetBrush( bkBrush ); | |
1214 | ||
1215 | dc.DrawRectangle( inRect.x, inRect.y, | |
1216 | inRect.width, inRect.height ); | |
1217 | ||
1218 | DrawRectShade( inRect, dc, 0, mpLayout->mLightPen, mpLayout->mDarkPen ); | |
1219 | } | |
1220 | ||
1221 | int cbRowDragPlugin::GetCollapsedIconsPos() | |
1222 | { | |
1223 | RowArrayT& rows = mpPane->GetRowList(); | |
1224 | ||
1225 | if ( rows.GetCount() == 0 ) | |
1226 | { | |
1227 | if ( mpPane->IsHorizontal() ) | |
1228 | ||
1229 | return mpPane->mBoundsInParent.y + mpPane->mTopMargin; | |
1230 | else | |
1231 | return mpPane->mBoundsInParent.x + mpPane->mLeftMargin; | |
1232 | } | |
1233 | ||
1234 | wxRect& bounds = rows[ rows.GetCount() - 1 ]->mBoundsInParent; | |
1235 | ||
1236 | if ( mpPane->IsHorizontal() ) | |
1237 | ||
1238 | return bounds.y + bounds.height + 1; | |
1239 | else | |
1240 | return bounds.x + bounds.width + 1; | |
1241 | ||
1242 | } | |
1243 | ||
1244 | void cbRowDragPlugin::GetRowHintRect( cbRowInfo* pRow, wxRect& rect ) | |
1245 | { | |
1246 | wxRect& bounds = pRow->mBoundsInParent; | |
1247 | ||
1248 | if ( mpPane->IsHorizontal() ) | |
1249 | { | |
1250 | rect.x = bounds.x - ROW_DRAG_HINT_WIDTH - 1; | |
1251 | rect.y = bounds.y; | |
1252 | rect.width = ROW_DRAG_HINT_WIDTH; | |
1253 | rect.height = bounds.height; | |
1254 | } | |
1255 | else | |
1256 | { | |
1257 | rect.x = bounds.x; | |
1258 | rect.y = bounds.y + bounds.height + 1; | |
1259 | rect.width = bounds.width; | |
1260 | rect.height = ROW_DRAG_HINT_WIDTH; | |
1261 | } | |
1262 | } | |
1263 | ||
1264 | void cbRowDragPlugin::GetCollapsedInconRect( int iconIdx, wxRect& rect ) | |
1265 | { | |
1266 | int upper = GetCollapsedIconsPos(); | |
1267 | ||
1268 | int right = (iconIdx == 0 ) | |
1269 | ? 0 : iconIdx * (COLLAPSED_ICON_WIDTH - COLLAPSED_ICON_HEIGHT); | |
1270 | ||
1271 | if ( mpPane->IsHorizontal() ) | |
1272 | { | |
1273 | rect.x = mpPane->mBoundsInParent.x + mpPane->mLeftMargin - ROW_DRAG_HINT_WIDTH - 1 | |
1274 | + right; | |
1275 | ||
1276 | rect.y = upper; | |
1277 | rect.width = COLLAPSED_ICON_WIDTH; | |
1278 | rect.height = COLLAPSED_ICON_HEIGHT; | |
1279 | } | |
1280 | else | |
1281 | { | |
1282 | rect.x = upper; | |
1283 | rect.y = mpPane->mBoundsInParent.y + mpPane->mBoundsInParent.height | |
1284 | - mpPane->mBottomMargin + ROW_DRAG_HINT_WIDTH + 1 | |
1285 | - right - COLLAPSED_ICON_WIDTH; | |
1286 | ||
1287 | rect.height = COLLAPSED_ICON_WIDTH; | |
1288 | rect.width = COLLAPSED_ICON_HEIGHT; | |
1289 | } | |
1290 | } | |
1291 | ||
1292 | /*** overridables ***/ | |
1293 | ||
1294 | void cbRowDragPlugin::DrawCollapsedRowIcon( int index, wxDC& dc, bool isHighlighted ) | |
1295 | { | |
1296 | wxRect rect; | |
1297 | GetCollapsedInconRect( index, rect ); | |
1298 | ||
1299 | wxBrush hiBrush ( mHightColor, wxSOLID ); | |
1300 | wxBrush lowBrush( mLowColor, wxSOLID ); | |
1301 | wxBrush& curBrush = ( isHighlighted ) ? hiBrush : lowBrush; | |
1302 | ||
1303 | if ( mpPane->IsHorizontal() ) | |
1304 | { | |
1305 | if ( index == 0 ) | |
1306 | ||
1307 | DrawOrtoRomb( rect, dc, curBrush ); | |
1308 | else | |
1309 | DrawRomb( rect, dc, curBrush ); | |
1310 | ||
1311 | int triOfs = (index == 0) ? TRIANGLE_OFFSET : TRIANGLE_OFFSET + COLLAPSED_ICON_HEIGHT; | |
1312 | ||
1313 | wxRect triRect; | |
1314 | triRect.x = triOfs + rect.x; | |
1315 | ||
1316 | triRect.width = ICON_TRIAN_HEIGHT; | |
1317 | triRect.y = rect.y; | |
1318 | triRect.height = rect.height; | |
1319 | ||
1320 | DrawTrianRight( triRect, dc ); | |
1321 | ||
1322 | wxRect patRect; | |
1323 | patRect.x = triOfs + ICON_TRIAN_HEIGHT + TRIANGLE_TO_PAT_GAP + rect.x; | |
1324 | patRect.y = rect.y + PAT_OFFSET; | |
1325 | patRect.width = rect.width - (patRect.x - rect.x) - COLLAPSED_ICON_HEIGHT - PAT_OFFSET; | |
1326 | patRect.height = rect.height - PAT_OFFSET*2; | |
1327 | ||
1328 | Draw3DPattern( patRect, dc ); | |
1329 | } | |
1330 | else | |
1331 | { | |
1332 | if ( index == 0 ) | |
1333 | ||
1334 | DrawOrtoRomb( rect, dc, curBrush ); | |
1335 | else | |
1336 | DrawRomb( rect, dc, curBrush ); | |
1337 | ||
1338 | int triOfs = (index == 0) | |
1339 | ? TRIANGLE_OFFSET + ICON_TRIAN_HEIGHT | |
1340 | : TRIANGLE_OFFSET + COLLAPSED_ICON_HEIGHT + ICON_TRIAN_HEIGHT; | |
1341 | ||
1342 | wxRect triRect; | |
1343 | triRect.y = rect.y + rect.height - triOfs; | |
1344 | triRect.x = rect.x; | |
1345 | triRect.width = rect.width; | |
1346 | triRect.height = ICON_TRIAN_HEIGHT; | |
1347 | ||
1348 | DrawTrianUp( triRect, dc ); | |
1349 | ||
1350 | wxRect patRect; | |
1351 | patRect.y = rect.y + COLLAPSED_ICON_HEIGHT + PAT_OFFSET; | |
1352 | patRect.x = rect.x + PAT_OFFSET; | |
1353 | patRect.width = rect.width - 2*PAT_OFFSET ; | |
1354 | patRect.height = rect.height - triOfs - 2*PAT_OFFSET - COLLAPSED_ICON_HEIGHT; | |
1355 | ||
1356 | Draw3DPattern( patRect, dc ); | |
1357 | } | |
1358 | } | |
1359 | ||
1360 | void cbRowDragPlugin::DrawRowDragHint( cbRowInfo* pRow , wxDC& dc, bool isHighlighted ) | |
1361 | { | |
1362 | wxRect rect; | |
1363 | GetRowHintRect( pRow, rect ); | |
1364 | ||
1365 | wxBrush hiBrush ( mHightColor, wxSOLID ); | |
1366 | wxBrush lowBrush( mLowColor, wxSOLID ); | |
1367 | wxBrush& curBrush = ( isHighlighted ) ? hiBrush : lowBrush; | |
1368 | ||
1369 | Draw3DRect( rect, dc, curBrush ); | |
1370 | ||
1371 | if ( mpPane->IsHorizontal() ) | |
1372 | { | |
1373 | wxRect triRect; | |
1374 | triRect.y = rect.y + TRIANGLE_OFFSET; | |
1375 | triRect.x = rect.x; | |
1376 | triRect.width = rect.width; | |
1377 | triRect.height = ICON_TRIAN_HEIGHT; | |
1378 | ||
1379 | DrawTrianDown( triRect, dc ); | |
1380 | ||
1381 | wxRect patRect; | |
1382 | patRect.x = rect.x + PAT_OFFSET; | |
1383 | patRect.y = rect.y + TRIANGLE_OFFSET + ICON_TRIAN_HEIGHT + TRIANGLE_TO_PAT_GAP; | |
1384 | patRect.width = rect.width - 2*PAT_OFFSET; | |
1385 | patRect.height = rect.height - ( patRect.y - rect.y ) - PAT_OFFSET; | |
1386 | Draw3DPattern( patRect, dc ); | |
1387 | ||
1388 | dc.SetPen( mpLayout->mLightPen ); | |
1389 | dc.DrawLine( rect.x, rect.y + rect.height, rect.x + rect.width, rect.y + rect.height ); | |
1390 | } | |
1391 | else | |
1392 | { | |
1393 | wxRect triRect; | |
1394 | triRect.x = rect.x + TRIANGLE_OFFSET; | |
1395 | triRect.y = rect.y; | |
1396 | triRect.height = rect.height; | |
1397 | triRect.width = ICON_TRIAN_HEIGHT; | |
1398 | ||
1399 | DrawTrianRight( triRect, dc ); | |
1400 | ||
1401 | wxRect patRect; | |
1402 | patRect.y = rect.y + PAT_OFFSET; | |
1403 | patRect.x = rect.x + TRIANGLE_OFFSET + ICON_TRIAN_HEIGHT + TRIANGLE_TO_PAT_GAP; | |
1404 | patRect.height = rect.height - 2*PAT_OFFSET; | |
1405 | patRect.width = rect.width - ( patRect.x - rect.x ) - PAT_OFFSET; | |
1406 | Draw3DPattern( patRect, dc ); | |
1407 | ||
1408 | dc.SetPen( mpLayout->mLightPen ); | |
1409 | dc.DrawLine( rect.x + rect.width, rect.y, rect.x + rect.width, rect.y + rect.height ); | |
1410 | } | |
1411 | } | |
1412 | ||
1413 | void cbRowDragPlugin::DrawRowsDragHintsBorder( wxDC& dc ) | |
1414 | { | |
1415 | // FIXME:: what was that? | |
1416 | } | |
1417 | ||
1418 | void cbRowDragPlugin::DrawCollapsedRowsBorder( wxDC& dc ) | |
1419 | { | |
1420 | int colRowOfs = GetCollapsedIconsPos(); | |
1421 | wxRect& bounds = mpPane->mBoundsInParent; | |
1422 | ||
1423 | wxBrush bkBrush( mpLayout->mGrayPen.GetColour(), wxSOLID ); | |
1424 | dc.SetBrush( bkBrush ); | |
1425 | dc.SetPen( mpLayout->mDarkPen ); | |
1426 | ||
1427 | if ( mpPane->IsHorizontal() ) | |
1428 | ||
1429 | dc.DrawRectangle( bounds.x + mpPane->mLeftMargin - ROW_DRAG_HINT_WIDTH - 1, | |
1430 | colRowOfs, | |
1431 | bounds.width - mpPane->mLeftMargin - mpPane->mRightMargin + 2 + ROW_DRAG_HINT_WIDTH, | |
1432 | COLLAPSED_ICON_HEIGHT + 1); | |
1433 | else | |
1434 | dc.DrawRectangle( colRowOfs, | |
1435 | bounds.y + mpPane->mTopMargin - 1, | |
1436 | COLLAPSED_ICON_HEIGHT + 1, | |
1437 | bounds.height - mpPane->mTopMargin - mpPane->mBottomMargin | |
1438 | - ROW_DRAG_HINT_WIDTH - 2 ); | |
1439 | ||
1440 | dc.SetBrush( wxNullBrush ); | |
1441 | } | |
1442 | ||
1443 | static inline bool rect_contains_point( const wxRect& rect, int x, int y ) | |
1444 | { | |
1445 | return ( x >= rect.x && | |
1446 | y >= rect.y && | |
1447 | x < rect.x + rect.width && | |
1448 | y < rect.y + rect.height ); | |
1449 | } | |
1450 | ||
1451 | bool cbRowDragPlugin::HitTestCollapsedRowIcon( int iconIdx, const wxPoint& pos ) | |
1452 | { | |
1453 | wxRect bounds; | |
1454 | GetCollapsedInconRect( iconIdx, bounds ); | |
1455 | ||
1456 | return rect_contains_point( bounds, pos.x, pos.y ); | |
1457 | } | |
1458 | ||
1459 | bool cbRowDragPlugin::HitTestRowDragHint( cbRowInfo* pRow, const wxPoint& pos ) | |
1460 | { | |
1461 | wxRect bounds; | |
1462 | GetRowHintRect( pRow, bounds ); | |
1463 | ||
1464 | return rect_contains_point( bounds, pos.x, pos.y ); | |
1465 | } | |
1466 |