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