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