]> git.saurik.com Git - wxWidgets.git/blob - src/generic/tbarsmpl.cpp
A little black magic... When the C++ object (for a window or
[wxWidgets.git] / src / generic / tbarsmpl.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: generic/tbarsmpl.cpp
3 // Purpose: wxToolBarSimple
4 // Author: Julian Smart
5 // Modified by: VZ on 14.12.99 during wxToolBarSimple reorganization
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "tbarsmpl.h"
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 #if wxUSE_TOOLBAR_SIMPLE
32
33 #ifndef WX_PRECOMP
34 #include "wx/settings.h"
35 #include "wx/window.h"
36 #include "wx/dcclient.h"
37 #include "wx/dcmemory.h"
38 #endif
39
40 #include "wx/tbarsmpl.h"
41
42 // ----------------------------------------------------------------------------
43 // private classes
44 // ----------------------------------------------------------------------------
45
46 class WXDLLEXPORT wxToolBarToolSimple : public wxToolBarToolBase
47 {
48 public:
49 wxToolBarToolSimple(wxToolBarSimple *tbar,
50 int id,
51 const wxString& label,
52 const wxBitmap& bmpNormal,
53 const wxBitmap& bmpDisabled,
54 wxItemKind kind,
55 wxObject *clientData,
56 const wxString& shortHelp,
57 const wxString& longHelp)
58 : wxToolBarToolBase(tbar, id, label, bmpNormal, bmpDisabled, kind,
59 clientData, shortHelp, longHelp)
60 {
61 }
62
63 wxToolBarToolSimple(wxToolBarSimple *tbar, wxControl *control)
64 : wxToolBarToolBase(tbar, control)
65 {
66 }
67
68 void SetSize(const wxSize& size)
69 {
70 m_width = size.x;
71 m_height = size.y;
72 }
73
74 wxCoord GetWidth() const { return m_width; }
75 wxCoord GetHeight() const { return m_height; }
76
77 wxCoord m_x;
78 wxCoord m_y;
79 wxCoord m_width;
80 wxCoord m_height;
81 };
82
83 // ----------------------------------------------------------------------------
84 // wxWin macros
85 // ----------------------------------------------------------------------------
86
87 IMPLEMENT_DYNAMIC_CLASS(wxToolBarSimple, wxToolBarBase)
88
89 #if !wxUSE_TOOLBAR_NATIVE
90 #include "wx/toolbar.h"
91
92 IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxToolBarSimple)
93 #endif
94
95 BEGIN_EVENT_TABLE(wxToolBarSimple, wxToolBarBase)
96 EVT_SIZE(wxToolBarSimple::OnSize)
97 EVT_SCROLL(wxToolBarSimple::OnScroll)
98 EVT_PAINT(wxToolBarSimple::OnPaint)
99 EVT_KILL_FOCUS(wxToolBarSimple::OnKillFocus)
100 EVT_MOUSE_EVENTS(wxToolBarSimple::OnMouseEvent)
101 END_EVENT_TABLE()
102
103 // ============================================================================
104 // implementation
105 // ============================================================================
106
107 // ----------------------------------------------------------------------------
108 // tool bar tools creation
109 // ----------------------------------------------------------------------------
110
111 wxToolBarToolBase *wxToolBarSimple::CreateTool(int id,
112 const wxString& label,
113 const wxBitmap& bmpNormal,
114 const wxBitmap& bmpDisabled,
115 wxItemKind kind,
116 wxObject *clientData,
117 const wxString& shortHelp,
118 const wxString& longHelp)
119 {
120 return new wxToolBarToolSimple(this, id, label, bmpNormal, bmpDisabled,
121 kind, clientData, shortHelp, longHelp);
122 }
123
124 wxToolBarToolBase *wxToolBarSimple::CreateTool(wxControl *control)
125 {
126 return new wxToolBarToolSimple(this, control);
127 }
128
129 // ----------------------------------------------------------------------------
130 // wxToolBarSimple creation
131 // ----------------------------------------------------------------------------
132
133 void wxToolBarSimple::Init()
134 {
135 m_currentRowsOrColumns = 0;
136
137 m_lastX =
138 m_lastY = 0;
139
140 m_maxWidth =
141 m_maxHeight = 0;
142
143 m_pressedTool =
144 m_currentTool = -1;
145
146 m_xPos =
147 m_yPos = -1;
148
149 m_toolPacking = 1;
150 m_toolSeparation = 5;
151
152 m_defaultWidth = 16;
153 m_defaultHeight = 15;
154
155 m_xScrollPixelsPerLine = 1;
156 m_yScrollPixelsPerLine = 1;
157 m_xScrollingEnabled = FALSE;
158 m_yScrollingEnabled = FALSE;
159 m_xScrollPosition = 0;
160 m_yScrollPosition = 0;
161 m_xScrollLines = 0;
162 m_yScrollLines = 0;
163 m_xScrollLinesPerPage = 0;
164 m_yScrollLinesPerPage = 0;
165 }
166
167 wxToolBarToolBase *wxToolBarSimple::DoAddTool(int id,
168 const wxString& label,
169 const wxBitmap& bitmap,
170 const wxBitmap& bmpDisabled,
171 wxItemKind kind,
172 const wxString& shortHelp,
173 const wxString& longHelp,
174 wxObject *clientData,
175 wxCoord xPos,
176 wxCoord yPos)
177 {
178 // rememeber the position for DoInsertTool()
179 m_xPos = xPos;
180 m_yPos = yPos;
181
182 return wxToolBarBase::DoAddTool(id, label, bitmap, bmpDisabled, kind,
183 shortHelp, longHelp,
184 clientData, xPos, yPos);
185 }
186
187 bool wxToolBarSimple::DoInsertTool(size_t WXUNUSED(pos),
188 wxToolBarToolBase *toolBase)
189 {
190 wxToolBarToolSimple *tool = (wxToolBarToolSimple *)toolBase;
191
192 wxCHECK_MSG( !tool->IsControl(), FALSE,
193 _T("generic wxToolBarSimple doesn't support controls") );
194
195 tool->m_x = m_xPos;
196 if ( tool->m_x == -1 )
197 tool->m_x = m_xMargin;
198
199 tool->m_y = m_yPos;
200 if ( tool->m_y == -1 )
201 tool->m_y = m_yMargin;
202
203 tool->SetSize(GetToolSize());
204
205 if ( tool->IsButton() )
206 {
207 // Calculate reasonable max size in case Layout() not called
208 if ((tool->m_x + tool->GetNormalBitmap().GetWidth() + m_xMargin) > m_maxWidth)
209 m_maxWidth = (wxCoord)((tool->m_x + tool->GetWidth() + m_xMargin));
210
211 if ((tool->m_y + tool->GetNormalBitmap().GetHeight() + m_yMargin) > m_maxHeight)
212 m_maxHeight = (wxCoord)((tool->m_y + tool->GetHeight() + m_yMargin));
213 }
214
215 return TRUE;
216 }
217
218 bool wxToolBarSimple::DoDeleteTool(size_t WXUNUSED(pos),
219 wxToolBarToolBase *tool)
220 {
221 // VZ: didn't test whether it works, but why not...
222 tool->Detach();
223
224 Refresh();
225
226 return TRUE;
227 }
228
229 bool wxToolBarSimple::Create(wxWindow *parent,
230 wxWindowID id,
231 const wxPoint& pos,
232 const wxSize& size,
233 long style,
234 const wxString& name)
235 {
236 if ( !wxWindow::Create(parent, id, pos, size, style, name) )
237 return FALSE;
238
239 // Set it to grey (or other 3D face colour)
240 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
241
242 if ( GetWindowStyleFlag() & wxTB_VERTICAL )
243 {
244 m_lastX = 7;
245 m_lastY = 3;
246
247 m_maxRows = 32000; // a lot
248 m_maxCols = 1;
249 }
250 else
251 {
252 m_lastX = 3;
253 m_lastY = 7;
254
255 m_maxRows = 1;
256 m_maxCols = 32000; // a lot
257 }
258
259 SetCursor(*wxSTANDARD_CURSOR);
260
261 return TRUE;
262 }
263
264 wxToolBarSimple::~wxToolBarSimple()
265 {
266 }
267
268 bool wxToolBarSimple::Realize()
269 {
270 m_currentRowsOrColumns = 0;
271 m_lastX = m_xMargin;
272 m_lastY = m_yMargin;
273 m_maxWidth = 0;
274 m_maxHeight = 0;
275
276 int maxToolWidth = 0;
277 int maxToolHeight = 0;
278
279 // Find the maximum tool width and height
280 wxToolBarToolsList::Node *node = m_tools.GetFirst();
281 while ( node )
282 {
283 wxToolBarToolSimple *tool = (wxToolBarToolSimple *)node->GetData();
284 if ( tool->GetWidth() > maxToolWidth )
285 maxToolWidth = tool->GetWidth();
286 if (tool->GetHeight() > maxToolHeight)
287 maxToolHeight = tool->GetHeight();
288
289 node = node->GetNext();
290 }
291
292 int separatorSize = m_toolSeparation;
293
294 node = m_tools.GetFirst();
295 while ( node )
296 {
297 wxToolBarToolSimple *tool = (wxToolBarToolSimple *)node->GetData();
298 if ( tool->IsSeparator() )
299 {
300 if ( GetWindowStyleFlag() & wxTB_HORIZONTAL )
301 {
302 if (m_currentRowsOrColumns >= m_maxCols)
303 m_lastY += separatorSize;
304 else
305 m_lastX += separatorSize;
306 }
307 else
308 {
309 if (m_currentRowsOrColumns >= m_maxRows)
310 m_lastX += separatorSize;
311 else
312 m_lastY += separatorSize;
313 }
314 }
315 else if ( tool->IsButton() )
316 {
317 if ( GetWindowStyleFlag() & wxTB_HORIZONTAL )
318 {
319 if (m_currentRowsOrColumns >= m_maxCols)
320 {
321 m_currentRowsOrColumns = 0;
322 m_lastX = m_xMargin;
323 m_lastY += maxToolHeight + m_toolPacking;
324 }
325 tool->m_x = (wxCoord)(m_lastX + (maxToolWidth - tool->GetWidth())/2.0);
326 tool->m_y = (wxCoord)(m_lastY + (maxToolHeight - tool->GetHeight())/2.0);
327
328 m_lastX += maxToolWidth + m_toolPacking;
329 }
330 else
331 {
332 if (m_currentRowsOrColumns >= m_maxRows)
333 {
334 m_currentRowsOrColumns = 0;
335 m_lastX += (maxToolWidth + m_toolPacking);
336 m_lastY = m_yMargin;
337 }
338 tool->m_x = (wxCoord)(m_lastX + (maxToolWidth - tool->GetWidth())/2.0);
339 tool->m_y = (wxCoord)(m_lastY + (maxToolHeight - tool->GetHeight())/2.0);
340
341 m_lastY += maxToolHeight + m_toolPacking;
342 }
343 m_currentRowsOrColumns ++;
344 }
345 else
346 {
347 // TODO: support the controls
348 }
349
350 if (m_lastX > m_maxWidth)
351 m_maxWidth = m_lastX;
352 if (m_lastY > m_maxHeight)
353 m_maxHeight = m_lastY;
354
355 node = node->GetNext();
356 }
357
358 if ( GetWindowStyleFlag() & wxTB_HORIZONTAL )
359 m_maxWidth += maxToolWidth;
360 else
361 m_maxHeight += maxToolHeight;
362
363 m_maxWidth += m_xMargin;
364 m_maxHeight += m_yMargin;
365
366 return TRUE;
367 }
368
369 // ----------------------------------------------------------------------------
370 // event handlers
371 // ----------------------------------------------------------------------------
372
373 void wxToolBarSimple::OnPaint (wxPaintEvent& WXUNUSED(event))
374 {
375 wxPaintDC dc(this);
376 PrepareDC(dc);
377
378 static int count = 0;
379 // Prevent reentry of OnPaint which would cause wxMemoryDC errors.
380 if ( count > 0 )
381 return;
382 count++;
383
384 for ( wxToolBarToolsList::Node *node = m_tools.GetFirst();
385 node;
386 node = node->GetNext() )
387 {
388 wxToolBarToolBase *tool = node->GetData();
389 if ( tool->IsButton() )
390 DrawTool(dc, tool);
391 }
392
393 count--;
394 }
395
396 void wxToolBarSimple::OnSize (wxSizeEvent& WXUNUSED(event))
397 {
398 #if wxUSE_CONSTRAINTS
399 if (GetAutoLayout())
400 Layout();
401 #endif
402
403 AdjustScrollbars();
404 }
405
406 void wxToolBarSimple::OnKillFocus(wxFocusEvent& WXUNUSED(event))
407 {
408 OnMouseEnter(m_pressedTool = m_currentTool = -1);
409 }
410
411 void wxToolBarSimple::OnMouseEvent(wxMouseEvent & event)
412 {
413 wxCoord x, y;
414 event.GetPosition(&x, &y);
415 wxToolBarToolSimple *tool = (wxToolBarToolSimple *)FindToolForPosition(x, y);
416
417 if (event.LeftDown())
418 {
419 CaptureMouse();
420 }
421 if (event.LeftUp())
422 {
423 ReleaseMouse();
424 }
425
426 if (!tool)
427 {
428 if (m_currentTool > -1)
429 {
430 if (event.LeftIsDown())
431 SpringUpButton(m_currentTool);
432 m_currentTool = -1;
433 OnMouseEnter(-1);
434 }
435 return;
436 }
437
438 if (!event.IsButton())
439 {
440 if ( tool->GetId() != m_currentTool )
441 {
442 // If the left button is kept down and moved over buttons,
443 // press those buttons.
444 if ( event.LeftIsDown() && tool->IsEnabled() )
445 {
446 SpringUpButton(m_currentTool);
447
448 if ( tool->CanBeToggled() )
449 {
450 tool->Toggle();
451 }
452
453 DrawTool(tool);
454 }
455
456 m_currentTool = tool->GetId();
457 OnMouseEnter(m_currentTool);
458 }
459 return;
460 }
461
462 // Left button pressed.
463 if ( event.LeftDown() && tool->IsEnabled() )
464 {
465 if ( tool->CanBeToggled() )
466 {
467 tool->Toggle();
468 }
469
470 DrawTool(tool);
471 }
472 else if (event.RightDown())
473 {
474 OnRightClick(tool->GetId(), x, y);
475 }
476
477 // Left Button Released. Only this action confirms selection.
478 // If the button is enabled and it is not a toggle tool and it is
479 // in the pressed state, then raise the button and call OnLeftClick.
480 //
481 if ( event.LeftUp() && tool->IsEnabled() )
482 {
483 // Pass the OnLeftClick event to tool
484 if ( !OnLeftClick(tool->GetId(), tool->IsToggled()) &&
485 tool->CanBeToggled() )
486 {
487 // If it was a toggle, and OnLeftClick says No Toggle allowed,
488 // then change it back
489 tool->Toggle();
490 }
491
492 DrawTool(tool);
493 }
494 }
495
496 // ----------------------------------------------------------------------------
497 // drawing
498 // ----------------------------------------------------------------------------
499
500 void wxToolBarSimple::DrawTool(wxToolBarToolBase *tool)
501 {
502 wxClientDC dc(this);
503 DrawTool(dc, tool);
504 }
505
506 void wxToolBarSimple::DrawTool(wxDC& dc, wxToolBarToolBase *toolBase)
507 {
508 wxToolBarToolSimple *tool = (wxToolBarToolSimple *)toolBase;
509
510 wxMemoryDC memDC;
511 PrepareDC(dc);
512
513 wxPen dark_grey_pen(wxColour( 85,85,85 ), 1, wxSOLID);
514 wxPen white_pen(wxT("WHITE"), 1, wxSOLID);
515 wxPen black_pen(wxT("BLACK"), 1, wxSOLID);
516
517 wxBitmap bitmap = tool->GetNormalBitmap();
518 if (!bitmap.Ok())
519 return;
520
521 if ( !tool->IsToggled() )
522 {
523 #if wxUSE_PALETTE
524 #ifndef __WXGTK__
525 if (bitmap.GetPalette())
526 memDC.SetPalette(*bitmap.GetPalette());
527 #endif
528 #endif // wxUSE_PALETTE
529
530 int ax = (int)tool->m_x,
531 ay = (int)tool->m_y,
532 bx = (int)(tool->m_x+tool->GetWidth()),
533 by = (int)(tool->m_y+tool->GetHeight());
534
535 memDC.SelectObject(bitmap);
536 if (m_windowStyle & wxTB_3DBUTTONS)
537 {
538 dc.SetClippingRegion(ax, ay, (bx-ax+1), (by-ay+1));
539 dc.Blit((ax+1), (ay+1), (bx-ax-2), (by-ay-2), &memDC, 0, 0);
540 wxPen * old_pen = & dc.GetPen();
541 dc.SetPen( white_pen );
542 dc.DrawLine(ax,(by-1),ax,ay);
543 dc.DrawLine(ax,ay,(bx-1),ay);
544 dc.SetPen( dark_grey_pen );
545 dc.DrawLine((bx-1),(ay+1),(bx-1),(by-1));
546 dc.DrawLine((bx-1),(by-1),(ax+1),(by-1));
547 dc.SetPen( black_pen );
548 dc.DrawLine(bx,ay,bx,by);
549 dc.DrawLine(bx,by,ax,by);
550 dc.SetPen( *old_pen );
551 dc.DestroyClippingRegion();
552 // Select bitmap out of the DC
553 }
554 else
555 {
556 dc.Blit(tool->m_x, tool->m_y,
557 bitmap.GetWidth(), bitmap.GetHeight(),
558 &memDC, 0, 0);
559 }
560 memDC.SelectObject(wxNullBitmap);
561
562 #if wxUSE_PALETTE
563 #ifndef __WXGTK__
564 if (bitmap.GetPalette())
565 memDC.SetPalette(wxNullPalette);
566 #endif
567 #endif // wxUSE_PALETTE
568 }
569 // No second bitmap, so draw a thick line around bitmap, or invert if mono
570 else if ( tool->IsToggled() )
571 {
572 bool drawBorder = FALSE;
573 #ifdef __X__ // X doesn't invert properly on colour
574 drawBorder = wxColourDisplay();
575 #else // Inversion works fine under Windows
576 drawBorder = FALSE;
577 #endif
578
579 if (!drawBorder)
580 {
581 memDC.SelectObject(tool->GetNormalBitmap());
582 dc.Blit(tool->m_x, tool->m_y, tool->GetWidth(), tool->GetHeight(),
583 &memDC, 0, 0, wxSRC_INVERT);
584 memDC.SelectObject(wxNullBitmap);
585 }
586 else
587 {
588 bitmap = tool->GetNormalBitmap();
589
590 if (m_windowStyle & wxTB_3DBUTTONS)
591 {
592 int ax = (int)tool->m_x,
593 ay = (int)tool->m_y,
594 bx = (int)(tool->m_x+tool->GetWidth()),
595 by = (int)(tool->m_y+tool->GetHeight());
596
597 memDC.SelectObject(bitmap);
598 dc.SetClippingRegion(ax, ay, (bx-ax+1), (by-ay+1));
599 dc.Blit((ax+2), (ay+2), (bx-ax-2), (by-ay-2), &memDC, 0, 0);
600 wxPen * old_pen = & dc.GetPen();
601 dc.SetPen( black_pen );
602 dc.DrawLine(ax,(by-1),ax,ay);
603 dc.DrawLine(ax,ay,(bx-1),ay);
604 dc.SetPen( dark_grey_pen );
605 dc.DrawLine((ax+1),(by-2),(ax+1),(ay+1));
606 dc.DrawLine((ax+1),(ay+1),(bx-2),(ay+1));
607 dc.SetPen( white_pen );
608 dc.DrawLine(bx,ay,bx,by);
609 dc.DrawLine(bx,by,ax,by);
610 dc.SetPen( *old_pen );
611 dc.DestroyClippingRegion();
612 memDC.SelectObject(wxNullBitmap);
613 }
614 else
615 {
616 wxCoord x = tool->m_x;
617 wxCoord y = tool->m_y;
618 wxCoord w = bitmap.GetWidth();
619 wxCoord h = bitmap.GetHeight();
620 wxPen thick_black_pen(wxT("BLACK"), 3, wxSOLID);
621
622 memDC.SelectObject(bitmap);
623 dc.SetClippingRegion(tool->m_x, tool->m_y, w, h);
624 dc.Blit(tool->m_x, tool->m_y, w, h,
625 &memDC, 0, 0);
626 dc.SetPen(thick_black_pen);
627 dc.SetBrush(*wxTRANSPARENT_BRUSH);
628 dc.DrawRectangle(x, y, w-1, h-1);
629 dc.DestroyClippingRegion();
630 memDC.SelectObject(wxNullBitmap);
631 }
632 }
633 }
634 }
635
636 // ----------------------------------------------------------------------------
637 // toolbar geometry
638 // ----------------------------------------------------------------------------
639
640 void wxToolBarSimple::SetRows(int nRows)
641 {
642 wxCHECK_RET( nRows != 0, _T("max number of rows must be > 0") );
643
644 m_maxCols = (GetToolsCount() + nRows - 1) / nRows;
645
646 AdjustScrollbars();
647 Refresh();
648 }
649
650 wxToolBarToolBase *wxToolBarSimple::FindToolForPosition(wxCoord x,
651 wxCoord y) const
652 {
653 wxToolBarToolsList::Node *node = m_tools.GetFirst();
654 while (node)
655 {
656 wxToolBarToolSimple *tool = (wxToolBarToolSimple *)node->GetData();
657 if ((x >= tool->m_x) && (y >= tool->m_y) &&
658 (x <= (tool->m_x + tool->GetWidth())) &&
659 (y <= (tool->m_y + tool->GetHeight())))
660 {
661 return tool;
662 }
663
664 node = node->GetNext();
665 }
666
667 return (wxToolBarToolBase *)NULL;
668 }
669
670 // ----------------------------------------------------------------------------
671 // tool state change handlers
672 // ----------------------------------------------------------------------------
673
674 void wxToolBarSimple::DoEnableTool(wxToolBarToolBase *tool,
675 bool WXUNUSED(enable))
676 {
677 DrawTool(tool);
678 }
679
680 void wxToolBarSimple::DoToggleTool(wxToolBarToolBase *tool,
681 bool WXUNUSED(toggle))
682 {
683 DrawTool(tool);
684 }
685
686 void wxToolBarSimple::DoSetToggle(wxToolBarToolBase * WXUNUSED(tool),
687 bool WXUNUSED(toggle))
688 {
689 // nothing to do
690 }
691
692 // Okay, so we've left the tool we're in ... we must check if the tool we're
693 // leaving was a 'sprung push button' and if so, spring it back to the up
694 // state.
695 void wxToolBarSimple::SpringUpButton(int id)
696 {
697 wxToolBarToolBase *tool = FindById(id);
698
699 if ( tool && tool->CanBeToggled() )
700 {
701 if (tool->IsToggled())
702 tool->Toggle();
703
704 DrawTool(tool);
705 }
706 }
707
708 // ----------------------------------------------------------------------------
709 // scrolling implementation
710 // ----------------------------------------------------------------------------
711
712 /*
713 * pixelsPerUnitX/pixelsPerUnitY: number of pixels per unit (e.g. pixels per text line)
714 * noUnitsX/noUnitsY: : no. units per scrollbar
715 */
716 void wxToolBarSimple::SetScrollbars (int pixelsPerUnitX, int pixelsPerUnitY,
717 int noUnitsX, int noUnitsY,
718 int xPos, int yPos)
719 {
720 m_xScrollPixelsPerLine = pixelsPerUnitX;
721 m_yScrollPixelsPerLine = pixelsPerUnitY;
722 m_xScrollLines = noUnitsX;
723 m_yScrollLines = noUnitsY;
724
725 int w, h;
726 GetSize(&w, &h);
727
728 // Recalculate scroll bar range and position
729 if (m_xScrollLines > 0)
730 {
731 m_xScrollPosition = xPos;
732 SetScrollPos (wxHORIZONTAL, m_xScrollPosition, TRUE);
733 }
734 else
735 {
736 SetScrollbar(wxHORIZONTAL, 0, 0, 0, FALSE);
737 m_xScrollPosition = 0;
738 }
739
740 if (m_yScrollLines > 0)
741 {
742 m_yScrollPosition = yPos;
743 SetScrollPos (wxVERTICAL, m_yScrollPosition, TRUE);
744 }
745 else
746 {
747 SetScrollbar(wxVERTICAL, 0, 0, 0, FALSE);
748 m_yScrollPosition = 0;
749 }
750 AdjustScrollbars();
751 Refresh();
752
753 #if 0 //def __WXMSW__
754 ::UpdateWindow ((HWND) GetHWND());
755 #endif
756 }
757
758 void wxToolBarSimple::OnScroll(wxScrollEvent& event)
759 {
760 int orient = event.GetOrientation();
761
762 int nScrollInc = CalcScrollInc(event);
763 if (nScrollInc == 0)
764 return;
765
766 if (orient == wxHORIZONTAL)
767 {
768 int newPos = m_xScrollPosition + nScrollInc;
769 SetScrollPos(wxHORIZONTAL, newPos, TRUE );
770 }
771 else
772 {
773 int newPos = m_yScrollPosition + nScrollInc;
774 SetScrollPos(wxVERTICAL, newPos, TRUE );
775 }
776
777 if (orient == wxHORIZONTAL)
778 {
779 if (m_xScrollingEnabled)
780 ScrollWindow(-m_xScrollPixelsPerLine * nScrollInc, 0, NULL);
781 else
782 Refresh();
783 }
784 else
785 {
786 if (m_yScrollingEnabled)
787 ScrollWindow(0, -m_yScrollPixelsPerLine * nScrollInc, NULL);
788 else
789 Refresh();
790 }
791
792 if (orient == wxHORIZONTAL)
793 {
794 m_xScrollPosition += nScrollInc;
795 }
796 else
797 {
798 m_yScrollPosition += nScrollInc;
799 }
800
801 }
802
803 int wxToolBarSimple::CalcScrollInc(wxScrollEvent& event)
804 {
805 int pos = event.GetPosition();
806 int orient = event.GetOrientation();
807
808 int nScrollInc = 0;
809 if (event.GetEventType() == wxEVT_SCROLL_TOP)
810 {
811 if (orient == wxHORIZONTAL)
812 nScrollInc = - m_xScrollPosition;
813 else
814 nScrollInc = - m_yScrollPosition;
815 } else
816 if (event.GetEventType() == wxEVT_SCROLL_BOTTOM)
817 {
818 if (orient == wxHORIZONTAL)
819 nScrollInc = m_xScrollLines - m_xScrollPosition;
820 else
821 nScrollInc = m_yScrollLines - m_yScrollPosition;
822 } else
823 if (event.GetEventType() == wxEVT_SCROLL_LINEUP)
824 {
825 nScrollInc = -1;
826 } else
827 if (event.GetEventType() == wxEVT_SCROLL_LINEDOWN)
828 {
829 nScrollInc = 1;
830 } else
831 if (event.GetEventType() == wxEVT_SCROLL_PAGEUP)
832 {
833 if (orient == wxHORIZONTAL)
834 nScrollInc = -GetScrollPageSize(wxHORIZONTAL);
835 else
836 nScrollInc = -GetScrollPageSize(wxVERTICAL);
837 } else
838 if (event.GetEventType() == wxEVT_SCROLL_PAGEDOWN)
839 {
840 if (orient == wxHORIZONTAL)
841 nScrollInc = GetScrollPageSize(wxHORIZONTAL);
842 else
843 nScrollInc = GetScrollPageSize(wxVERTICAL);
844 } else
845 if ((event.GetEventType() == wxEVT_SCROLL_THUMBTRACK) ||
846 (event.GetEventType() == wxEVT_SCROLL_THUMBRELEASE))
847 {
848 if (orient == wxHORIZONTAL)
849 nScrollInc = pos - m_xScrollPosition;
850 else
851 nScrollInc = pos - m_yScrollPosition;
852 }
853
854 if (orient == wxHORIZONTAL)
855 {
856 int w, h;
857 GetClientSize(&w, &h);
858
859 int nMaxWidth = m_xScrollLines*m_xScrollPixelsPerLine;
860 int noPositions = (int) ( ((nMaxWidth - w)/(float)m_xScrollPixelsPerLine) + 0.5 );
861 if (noPositions < 0)
862 noPositions = 0;
863
864 if ( (m_xScrollPosition + nScrollInc) < 0 )
865 nScrollInc = -m_xScrollPosition; // As -ve as we can go
866 else if ( (m_xScrollPosition + nScrollInc) > noPositions )
867 nScrollInc = noPositions - m_xScrollPosition; // As +ve as we can go
868
869 return nScrollInc;
870 }
871 else
872 {
873 int w, h;
874 GetClientSize(&w, &h);
875
876 int nMaxHeight = m_yScrollLines*m_yScrollPixelsPerLine;
877 int noPositions = (int) ( ((nMaxHeight - h)/(float)m_yScrollPixelsPerLine) + 0.5 );
878 if (noPositions < 0)
879 noPositions = 0;
880
881 if ( (m_yScrollPosition + nScrollInc) < 0 )
882 nScrollInc = -m_yScrollPosition; // As -ve as we can go
883 else if ( (m_yScrollPosition + nScrollInc) > noPositions )
884 nScrollInc = noPositions - m_yScrollPosition; // As +ve as we can go
885
886 return nScrollInc;
887 }
888 }
889
890 // Adjust the scrollbars - new version.
891 void wxToolBarSimple::AdjustScrollbars()
892 {
893 int w, h;
894 GetClientSize(&w, &h);
895
896 // Recalculate scroll bar range and position
897 if (m_xScrollLines > 0)
898 {
899 int nMaxWidth = m_xScrollLines*m_xScrollPixelsPerLine;
900 int newRange = (int) ( ((nMaxWidth)/(float)m_xScrollPixelsPerLine) + 0.5 );
901 if (newRange < 0)
902 newRange = 0;
903
904 m_xScrollPosition = wxMin(newRange, m_xScrollPosition);
905
906 // Calculate page size i.e. number of scroll units you get on the
907 // current client window
908 int noPagePositions = (int) ( (w/(float)m_xScrollPixelsPerLine) + 0.5 );
909 if (noPagePositions < 1)
910 noPagePositions = 1;
911
912 SetScrollbar(wxHORIZONTAL, m_xScrollPosition, noPagePositions, newRange);
913 SetScrollPageSize(wxHORIZONTAL, noPagePositions);
914 }
915 if (m_yScrollLines > 0)
916 {
917 int nMaxHeight = m_yScrollLines*m_yScrollPixelsPerLine;
918 int newRange = (int) ( ((nMaxHeight)/(float)m_yScrollPixelsPerLine) + 0.5 );
919 if (newRange < 0)
920 newRange = 0;
921
922 m_yScrollPosition = wxMin(newRange, m_yScrollPosition);
923
924 // Calculate page size i.e. number of scroll units you get on the
925 // current client window
926 int noPagePositions = (int) ( (h/(float)m_yScrollPixelsPerLine) + 0.5 );
927 if (noPagePositions < 1)
928 noPagePositions = 1;
929
930 SetScrollbar(wxVERTICAL, m_yScrollPosition, noPagePositions, newRange);
931 SetScrollPageSize(wxVERTICAL, noPagePositions);
932 }
933 }
934
935 // Prepare the DC by translating it according to the current scroll position
936 void wxToolBarSimple::PrepareDC(wxDC& dc)
937 {
938 dc.SetDeviceOrigin(- m_xScrollPosition * m_xScrollPixelsPerLine, - m_yScrollPosition * m_yScrollPixelsPerLine);
939 }
940
941 void wxToolBarSimple::GetScrollPixelsPerUnit (int *x_unit, int *y_unit) const
942 {
943 *x_unit = m_xScrollPixelsPerLine;
944 *y_unit = m_yScrollPixelsPerLine;
945 }
946
947 int wxToolBarSimple::GetScrollPageSize(int orient) const
948 {
949 if ( orient == wxHORIZONTAL )
950 return m_xScrollLinesPerPage;
951 else
952 return m_yScrollLinesPerPage;
953 }
954
955 void wxToolBarSimple::SetScrollPageSize(int orient, int pageSize)
956 {
957 if ( orient == wxHORIZONTAL )
958 m_xScrollLinesPerPage = pageSize;
959 else
960 m_yScrollLinesPerPage = pageSize;
961 }
962
963 /*
964 * Scroll to given position (scroll position, not pixel position)
965 */
966 void wxToolBarSimple::Scroll (int x_pos, int y_pos)
967 {
968 int old_x, old_y;
969 ViewStart (&old_x, &old_y);
970 if (((x_pos == -1) || (x_pos == old_x)) && ((y_pos == -1) || (y_pos == old_y)))
971 return;
972
973 if (x_pos > -1)
974 {
975 m_xScrollPosition = x_pos;
976 SetScrollPos (wxHORIZONTAL, x_pos, TRUE);
977 }
978 if (y_pos > -1)
979 {
980 m_yScrollPosition = y_pos;
981 SetScrollPos (wxVERTICAL, y_pos, TRUE);
982 }
983 Refresh();
984
985 #if 0 //def __WXMSW__
986 UpdateWindow ((HWND) GetHWND());
987 #endif
988 }
989
990 void wxToolBarSimple::EnableScrolling (bool x_scroll, bool y_scroll)
991 {
992 m_xScrollingEnabled = x_scroll;
993 m_yScrollingEnabled = y_scroll;
994 }
995
996 void wxToolBarSimple::GetVirtualSize (int *x, int *y) const
997 {
998 *x = m_xScrollPixelsPerLine * m_xScrollLines;
999 *y = m_yScrollPixelsPerLine * m_yScrollLines;
1000 }
1001
1002 // Where the current view starts from
1003 void wxToolBarSimple::ViewStart (int *x, int *y) const
1004 {
1005 *x = m_xScrollPosition;
1006 *y = m_yScrollPosition;
1007 }
1008
1009 #endif // wxUSE_TOOLBAR_SIMPLE