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