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