]> git.saurik.com Git - wxWidgets.git/blame - contrib/src/fl/barhintspl.cpp
Various tweaks, fixes, and additions
[wxWidgets.git] / contrib / src / fl / barhintspl.cpp
CommitLineData
8e08b761
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: No names yet.
3// Purpose: Contrib. demo
4// Author: Aleksandras Gluchovas
5// Modified by:
6// Created: 30/11/98 (my 22th birthday :-)
7// RCS-ID: $Id$
8// Copyright: (c) Aleksandras Gluchovas
9// Licence: wxWindows license
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13 #pragma implementation "barhintspl.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/utils.h"
28#include "wx/fl/barhintspl.h"
29
30// fixed settings
31
32#define GROOVE_WIDTH 3 // left shade + middle line + right shade
33#define GROOVE_TO_GROOVE_GAP 1
34#define BOX_T_BOX_GAP 2
35#define BOX_TO_GROOVE_GAP 3
36
37#define BOXES_IN_HINT 2
38#define CLOSE_BOX_IDX 0
39#define COLLAPSE_BOX_IDX 1
40
41// used interally
42
43#define CLOSE_BOX_HITTED 1
44#define COLLAPSE_BOX_HITTED 2
45
46/***** Implementation fro class cbBarHintsPlugin *****/
47
48IMPLEMENT_DYNAMIC_CLASS( cbBarHintsPlugin, cbPluginBase )
49
50BEGIN_EVENT_TABLE( cbBarHintsPlugin, cbPluginBase )
51
52 EVT_PL_SIZE_BAR_WND ( cbBarHintsPlugin::OnSizeBarWindow )
53 EVT_PL_DRAW_BAR_DECOR( cbBarHintsPlugin::OnDrawBarDecorations )
54
55 EVT_PL_LEFT_DOWN( cbBarHintsPlugin::OnLeftDown )
56 EVT_PL_LEFT_UP ( cbBarHintsPlugin::OnLeftUp )
57 EVT_PL_MOTION ( cbBarHintsPlugin::OnMotion )
58
59END_EVENT_TABLE()
60
61cbBarHintsPlugin::cbBarHintsPlugin(void)
62
63 : mpPane( 0 ),
64 mBtnPressed ( FALSE ),
65 mCloseBoxOn ( TRUE ),
66 mCollapseBoxOn( TRUE ),
67 mGrooveCount ( 2 ),
68 mHintGap ( 4 ),
69 mXWeight ( 2 )
70{
71 mBoxes[CLOSE_BOX_IDX] = NULL;
72 mBoxes[COLLAPSE_BOX_IDX] = NULL;
73}
74
75cbBarHintsPlugin::cbBarHintsPlugin( wxFrameLayout* pLayout, int paneMask )
76
77 : cbPluginBase( pLayout, paneMask ),
78 mpPane( 0 ),
79 mBtnPressed ( FALSE ),
80 mCloseBoxOn ( TRUE ),
81 mCollapseBoxOn( TRUE ),
82 mGrooveCount ( 2 ),
83 mHintGap ( 5 ),
84 mXWeight ( 2 )
85{
86 mBoxes[CLOSE_BOX_IDX] = NULL;
87 mBoxes[COLLAPSE_BOX_IDX] = NULL;
88}
89
90
91cbBarHintsPlugin::~cbBarHintsPlugin()
92{
93 if (mBoxes[CLOSE_BOX_IDX])
94 delete mBoxes[CLOSE_BOX_IDX];
95
96 if (mBoxes[COLLAPSE_BOX_IDX])
97 delete mBoxes[COLLAPSE_BOX_IDX];
98} // cbBarHintsPlugin destructor
99
100
101void cbBarHintsPlugin::SetGrooveCount( int nGrooves )
102{
103 mGrooveCount = nGrooves;
104}
105
106void cbBarHintsPlugin::CreateBoxes()
107{
108 cbCloseBox* box1 = new cbCloseBox();
109 cbCollapseBox* box2 = new cbCollapseBox();
110
111 mBoxes[CLOSE_BOX_IDX] = box1;
112 mBoxes[COLLAPSE_BOX_IDX] = box2;
113
114 int i;
115 for( i = 0; i != BOXES_IN_HINT; ++i )
116 {
117 mBoxes[i]->mpLayout = mpLayout;
118 mBoxes[i]->mpPlugin = this;
119 mBoxes[i]->mpWnd = NULL;
120 }
121}
122
123
124void cbBarHintsPlugin::Draw3DBox( wxDC& dc, const wxPoint& pos, bool pressed )
125{
126}
127
128void cbBarHintsPlugin::DrawCloseBox( wxDC& dc, const wxPoint& pos, bool pressed )
129{
130}
131
132void cbBarHintsPlugin::DrawCollapseBox( wxDC& dc, const wxPoint& pos,
133 bool atLeft, bool disabled, bool pressed )
134{
135}
136
137void cbBarHintsPlugin::DrawGrooves( wxDC& dc, const wxPoint& pos, int length )
138{
139 int ofs = 0;
140
141 int i;
142 for( i = 0; i != mGrooveCount; ++i, ofs += ( GROOVE_WIDTH + GROOVE_TO_GROOVE_GAP ) )
143
144 if ( mpPane->IsHorizontal() )
145 {
146 dc.SetPen( mpLayout->mLightPen );
147 dc.DrawLine( pos.x + ofs, pos.y, pos.x + ofs, pos.y + length - 1 );
148 dc.DrawPoint( pos.x + ofs + 1, pos.y );
149
150 dc.SetPen( mpLayout->mDarkPen );
151 dc.DrawLine( pos.x + ofs + 2, pos.y, pos.x + ofs + 2, pos.y + length );
152 dc.DrawPoint( pos.x + ofs + 1, pos.y + length - 1 );
153 dc.DrawPoint( pos.x + ofs, pos.y + length - 1 );
154 }
155 else
156 {
157 dc.SetPen( mpLayout->mLightPen );
158 dc.DrawLine( pos.x, pos.y + ofs, pos.x + length - 1, pos.y + ofs );
159 dc.DrawPoint( pos.x, pos.y + ofs + 1 );
160
161 dc.SetPen( mpLayout->mDarkPen );
162 dc.DrawLine( pos.x, pos.y + ofs + 2, pos.x + length, pos.y + ofs + 2 );
163 dc.DrawPoint( pos.x + length - 1, pos.y + ofs + 1 );
164 dc.DrawPoint( pos.x + length - 1, pos.y + ofs );
165 }
166}
167
168void cbBarHintsPlugin::ExcludeHints( wxRect& rect, cbBarInfo& info )
169{
170 int boxHeight = BTN_BOX_HEIGHT;
171
172 // collapse and close box are not placed on fixed bars
173
174 if ( info.IsFixed() || ( !mCloseBoxOn && !mCollapseBoxOn ) )
175
176 boxHeight = 0;
177
178 int height = wxMax( mGrooveCount*(GROOVE_WIDTH + GROOVE_TO_GROOVE_GAP)
179 - GROOVE_TO_GROOVE_GAP,
180 boxHeight
181 );
182
183 if ( mpPane->IsHorizontal() )
184 {
185 rect.x += ( mHintGap*2 + height );
186 rect.width -= (height + 2*mHintGap);
187
188 rect.x -= info.mDimInfo.mHorizGap + 2;
189 rect.width += info.mDimInfo.mHorizGap + 2;
190 }
191 else
192 {
193 rect.y += (mHintGap*2 + height);
194 rect.height -= (height + 2*mHintGap);
195
196 rect.y -= info.mDimInfo.mVertGap + 2;
197 rect.height += info.mDimInfo.mVertGap + 2;
198 }
199}
200
201void cbBarHintsPlugin::DoDrawHint( wxDC& dc, wxRect& rect,
202 int pos, int boxOfs, int grooveOfs,
203 bool isFixed )
204{
205 if ( !isFixed )
206 {
207 if ( mpPane->IsHorizontal() )
208 {
209 if ( mCloseBoxOn )
210
211 mBoxes[CLOSE_BOX_IDX]->Draw( dc );
212
213 if ( mCollapseBoxOn )
214
215 mBoxes[COLLAPSE_BOX_IDX]->Draw( dc );
216 }
217 else
218 {
219 if ( mCloseBoxOn )
220
221 mBoxes[CLOSE_BOX_IDX]->Draw( dc );
222
223 if ( mCollapseBoxOn )
224
225 mBoxes[COLLAPSE_BOX_IDX]->Draw( dc );
226 }
227 }
228
229 if ( mpPane->IsHorizontal() )
230
231 DrawGrooves( dc, wxPoint( rect.x + mHintGap + grooveOfs, pos ),
232 rect.height - (pos - rect.y) - mHintGap );
233 else
234 DrawGrooves( dc, wxPoint( rect.x + mHintGap, rect.y + mHintGap + grooveOfs ),
235 (pos - rect.x) - mHintGap );
236}
237
238void cbBarHintsPlugin::GetHintsLayout( wxRect& rect, cbBarInfo& info,
239 int& boxOfs, int& grooveOfs, int& pos )
240{
241 int boxHeight = BTN_BOX_HEIGHT;
242 int boxWidth = BTN_BOX_WIDTH + BOX_TO_GROOVE_GAP + BTN_BOX_WIDTH;
243
244 // collapse and close box are not placed on fixed bars
245
246 if ( info.IsFixed() || ( !mCloseBoxOn && !mCollapseBoxOn ) )
247 {
248 boxHeight = 0;
249 boxWidth = 0;
250 }
251 else
252 if ( !mCloseBoxOn || !mCollapseBoxOn )
253
254 boxWidth = BTN_BOX_WIDTH;
255
256 int grooveHeight = mGrooveCount*(GROOVE_WIDTH + GROOVE_TO_GROOVE_GAP)
257 - GROOVE_TO_GROOVE_GAP;
258
259 int height = wxMax( grooveHeight, boxHeight );
260
261 // center boxs and groves with respect to each other
262
263 boxOfs = ( height - boxHeight ) / 2;
264 grooveOfs = ( height - grooveHeight ) / 2;
265
266 pos = ( mpPane->IsHorizontal() ) ? rect.y + mHintGap
267 : rect.x + rect.width - mHintGap;
268
269 // setup positions for boxes
270
271 if ( !info.IsFixed() )
272 {
273 // what direction "collapse-triangle" should look at?
274
275 bool& isAtLeft = ((cbCollapseBox*)(mBoxes[COLLAPSE_BOX_IDX]))->mIsAtLeft;
276
277 isAtLeft= info.mBounds.x <= mpPane->mPaneWidth - ( info.mBounds.x + info.mBounds.width );
278
279 if ( info.IsExpanded() )
280 {
281 isAtLeft = FALSE;
282
283 cbBarInfo* pCur = info.mpPrev;
284
285 while( pCur )
286 {
287 if ( !pCur->IsFixed() )
288 {
289 isAtLeft = TRUE; break;
290 }
291
292 pCur = pCur->mpPrev;
293 }
294 }
295
296 // collapse/expand works only when more not-fixed bars are present in the same row
297
298 mBoxes[COLLAPSE_BOX_IDX]->Enable( info.mpRow->mNotFixedBarsCnt > 1 );
299
300 int i;
301 for( i = 0; i != BOXES_IN_HINT; ++i )
302
303 mBoxes[i]->mpPane = mpPane;
304
305
306 if ( mpPane->IsHorizontal() )
307 {
308 if ( mCloseBoxOn )
309 {
310 mBoxes[CLOSE_BOX_IDX]->mPos = wxPoint( rect.x + mHintGap + boxOfs, pos );
311
312 pos += BTN_BOX_HEIGHT;
313 }
314
315 if ( mCollapseBoxOn )
316 {
317 if ( mCloseBoxOn ) pos += BOX_T_BOX_GAP;
318
319 mBoxes[COLLAPSE_BOX_IDX]->mPos = wxPoint( rect.x + mHintGap + boxOfs, pos );
320
321 pos += BTN_BOX_HEIGHT;
322
323 pos += BOX_TO_GROOVE_GAP;
324 }
325 }
326 else
327 {
328 if ( mCloseBoxOn )
329 {
330 pos -= BTN_BOX_WIDTH;
331
332 mBoxes[CLOSE_BOX_IDX]->mPos = wxPoint( pos , rect.y + mHintGap + boxOfs );
333 }
334
335 if ( mCollapseBoxOn )
336 {
337 if ( mCloseBoxOn ) pos -= BOX_T_BOX_GAP;
338
339 pos -= BTN_BOX_WIDTH;
340
341 mBoxes[COLLAPSE_BOX_IDX]->mPos = wxPoint( pos, rect.y + mHintGap + boxOfs );
342
343 pos -= BOX_TO_GROOVE_GAP;
344 }
345 }
346 }
347}
348
349static inline bool is_in_box( const wxPoint& rectPos, const wxPoint& mousePos )
350{
351 return ( mousePos.x >= rectPos.x &&
352 mousePos.y >= rectPos.y &&
353 mousePos.x < rectPos.x + BTN_BOX_WIDTH &&
354 mousePos.y < rectPos.y + BTN_BOX_HEIGHT );
355}
356
357int cbBarHintsPlugin::HitTestHints( cbBarInfo& info, const wxPoint& pos )
358{
359 wxPoint inPane = pos;
360 mpPane->PaneToFrame( &inPane.x, &inPane.y );
361
362 wxRect& rect = info.mBoundsInParent;
363
364 if ( info.IsFixed() ) return FALSE;
365
366 int boxOfs, grooveOfs, coord;
367
368 GetHintsLayout( rect, info, boxOfs, grooveOfs, coord );
369
370 if ( mpPane->IsHorizontal() )
371 {
372 if ( mCloseBoxOn )
373 {
374 if ( is_in_box( wxPoint( rect.x + mHintGap + boxOfs, coord ), inPane ) )
375
376 return CLOSE_BOX_HITTED;
377
378 coord += BTN_BOX_HEIGHT;
379 }
380
381 if ( mCollapseBoxOn )
382 {
383 if ( mCloseBoxOn ) coord += BOX_T_BOX_GAP;
384
385 if ( is_in_box( wxPoint( rect.x + mHintGap + boxOfs, coord ), inPane ) )
386
387 return COLLAPSE_BOX_HITTED;
388
389 coord += BTN_BOX_HEIGHT;
390 }
391 }
392 else
393 {
394 if ( mCloseBoxOn )
395 {
396 coord -= BTN_BOX_WIDTH;
397
398 if ( is_in_box( wxPoint( coord , rect.y + mHintGap + boxOfs ), inPane ) )
399
400 return CLOSE_BOX_HITTED;
401 }
402
403 if ( mCollapseBoxOn )
404 {
405 if ( mCloseBoxOn ) coord -= BOX_T_BOX_GAP;
406 coord -= BTN_BOX_WIDTH;
407
408 if ( is_in_box( wxPoint( coord, rect.y + mHintGap + boxOfs ), inPane ) )
409
410 return COLLAPSE_BOX_HITTED;
411 }
412 }
413
414 return FALSE;
415}
416
417// handlers for plugin-events
418
419void cbBarHintsPlugin::OnSizeBarWindow( cbSizeBarWndEvent& event )
420{
421 wxRect& rect = event.mBoundsInParent;
422 mpPane = event.mpPane;
423
424 ExcludeHints( rect, *event.mpBar );
425
426 event.Skip(); // pass event to the next plugin in the chain
427}
428
429void cbBarHintsPlugin::OnDrawBarDecorations( cbDrawBarDecorEvent& event )
430{
431 wxRect& rect = event.mBoundsInParent;
432 mpPane = event.mpPane;
433
434 int boxOfs, grooveOfs, pos;
435
436 GetHintsLayout( rect, *event.mpBar, boxOfs, grooveOfs, pos );
437
438 DoDrawHint( *event.mpDc, rect, pos, boxOfs, grooveOfs, event.mpBar->IsFixed() );
439
440 // let other plugins add on their decorations
441
442 event.Skip();
443}
444
445void cbBarHintsPlugin::OnLeftDown( cbLeftDownEvent& event )
446{
447 mpPane = event.mpPane;
448
449 wxPoint inFrame = event.mPos;
450 mpPane->PaneToFrame( &inFrame.x, &inFrame.y );
451
452 wxBarIterator iter( mpPane->GetRowList() );
453
454 mpClickedBar = NULL;
455
456 while ( iter.Next() )
457 {
458 cbBarInfo& bar = iter.BarInfo();
459
460 int boxOfs, grooveOfs, pos;
461
462 GetHintsLayout( bar.mBoundsInParent, bar, boxOfs, grooveOfs, pos );
463
464 if ( !bar.IsFixed() )
465 {
466 int i;
467 for( i = 0; i != BOXES_IN_HINT; ++i )
468 {
469 mBoxes[i]->OnLeftDown( inFrame );
470
471 if ( mBoxes[i]->mPressed )
472 {
473 mBtnPressed = TRUE;
474 mpClickedBar = &bar;
475
476 return; // event handled
477 }
478 }
479 }
480 }
481
482 event.Skip();
483}
484
485void cbBarHintsPlugin::OnLeftUp( cbLeftUpEvent& event )
486{
487 if ( mBtnPressed )
488 {
489 wxPoint inFrame = event.mPos;
490 mpPane->PaneToFrame( &inFrame.x, &inFrame.y );
491
492 int boxOfs, grooveOfs, pos;
493
494 GetHintsLayout( mpClickedBar->mBoundsInParent, *mpClickedBar, boxOfs, grooveOfs, pos );
495
496 int result = HitTestHints( *mpClickedBar, event.mPos );
497
498 int i;
499 for( i = 0; i != BOXES_IN_HINT; ++i )
500 {
501 mBoxes[i]->OnLeftUp( inFrame );
502
503 if ( mBoxes[i]->WasClicked() )
504 {
505 if ( i == 0 )
506
507 mpLayout->SetBarState( mpClickedBar, wxCBAR_HIDDEN, TRUE );
508 else
509 {
510 if ( mpClickedBar->IsExpanded() )
511
512 mpPane->ContractBar( mpClickedBar );
513 else
514 mpPane->ExpandBar( mpClickedBar );
515 }
516 }
517 }
518
519 mBtnPressed = FALSE;
520 return;
521 }
522 else
523 event.Skip();
524}
525
526void cbBarHintsPlugin::OnMotion( cbMotionEvent& event )
527{
528 if ( mBtnPressed )
529 {
530 wxPoint inFrame = event.mPos;
531 mpPane->PaneToFrame( &inFrame.x, &inFrame.y );
532
533 mpPane = event.mpPane;
534
535 int i;
536 for( i = 0; i != BOXES_IN_HINT; ++i )
537
538 mBoxes[i]->OnMotion( inFrame );
539 }
540 else
541 event.Skip();
542}
543
544void cbBarHintsPlugin::OnInitPlugin()
545{
546 cbPluginBase::OnInitPlugin();
547
548 cbDockPane** panes = mpLayout->GetPanesArray();
549
550 int i;
551 for( i = 0; i != MAX_PANES; ++i )
552 {
553 if ( panes[i]->MatchesMask( mPaneMask ) )
554 {
555 panes[i]->mProps.mMinCBarDim.x = 25;
556 panes[i]->mProps.mMinCBarDim.y = 16;
557 }
558 }
559 CreateBoxes();
560}