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