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