]>
Commit | Line | Data |
---|---|---|
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 | ||
48 | IMPLEMENT_DYNAMIC_CLASS( cbBarHintsPlugin, cbPluginBase ) | |
49 | ||
50 | BEGIN_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 | ||
59 | END_EVENT_TABLE() | |
60 | ||
61 | cbBarHintsPlugin::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 | ||
75 | cbBarHintsPlugin::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 | ||
91 | cbBarHintsPlugin::~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 | ||
101 | void cbBarHintsPlugin::SetGrooveCount( int nGrooves ) | |
102 | { | |
103 | mGrooveCount = nGrooves; | |
104 | } | |
105 | ||
106 | void 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 | ||
124 | void cbBarHintsPlugin::Draw3DBox( wxDC& dc, const wxPoint& pos, bool pressed ) | |
125 | { | |
126 | } | |
127 | ||
128 | void cbBarHintsPlugin::DrawCloseBox( wxDC& dc, const wxPoint& pos, bool pressed ) | |
129 | { | |
130 | } | |
131 | ||
132 | void cbBarHintsPlugin::DrawCollapseBox( wxDC& dc, const wxPoint& pos, | |
133 | bool atLeft, bool disabled, bool pressed ) | |
134 | { | |
135 | } | |
136 | ||
137 | void 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 | ||
168 | void 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 | ||
201 | void 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 | ||
238 | void 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 | ||
349 | static 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 | ||
357 | int 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 | ||
419 | void 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 | ||
429 | void 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 | ||
445 | void 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 | ||
485 | void 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 | ||
526 | void 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 | ||
544 | void 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 | } |