1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxToolBarSimple
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "tbarsmpl.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
29 #include "wx/tbarsmpl.h"
31 #if !USE_SHARED_LIBRARY
32 IMPLEMENT_DYNAMIC_CLASS(wxToolBarSimple
, wxToolBarBase
)
34 BEGIN_EVENT_TABLE(wxToolBarSimple
, wxToolBarBase
)
35 EVT_SIZE(wxToolBarSimple::OnSize
)
36 EVT_PAINT(wxToolBarSimple::OnPaint
)
37 EVT_KILL_FOCUS(wxToolBarSimple::OnKillFocus
)
38 EVT_MOUSE_EVENTS(wxToolBarSimple::OnMouseEvent
)
42 // TODO: eliminate these; use system colours
43 static wxPen
* white_pen
= NULL
,
44 * dark_grey_pen
= NULL
,
48 wxToolBarSimple::wxToolBarSimple(void)
50 m_currentRowsOrColumns
= 0;
55 bool wxToolBarSimple::Create(wxWindow
*parent
, wxWindowID id
, const wxPoint
& pos
, const wxSize
& size
, long style
,
56 const wxString
& name
)
58 if ( ! wxWindow::Create(parent
, id
, pos
, size
, style
, name
) )
61 // Set it to grey (or other 3D face colour)
62 wxSystemSettings settings
;
63 SetBackgroundColour(settings
.GetSystemColour(wxSYS_COLOUR_3DFACE
));
64 SetDefaultBackgroundColour(settings
.GetSystemColour(wxSYS_COLOUR_3DFACE
));
68 white_pen
= new wxPen
;
69 white_pen
->SetColour( "WHITE" );
71 if ( dark_grey_pen
== 0 )
73 dark_grey_pen
= new wxPen
;
74 dark_grey_pen
->SetColour( 85,85,85 );
78 black_pen
= new wxPen
;
79 black_pen
->SetColour( "BLACK" );
81 if ( thick_black_pen
== 0 )
83 thick_black_pen
= new wxPen("BLACK", 3, wxSOLID
);
85 if ( GetWindowStyleFlag() & wxTB_VERTICAL
)
86 { m_lastX
= 7; m_lastY
= 3; }
88 { m_lastX
= 3; m_lastY
= 7; }
89 m_maxWidth
= m_maxHeight
= 0;
90 m_pressedTool
= m_currentTool
= -1;
99 wxToolBarSimple::~wxToolBarSimple ()
103 void wxToolBarSimple::OnPaint (wxPaintEvent
& event
)
108 static int count
= 0;
109 // Prevent reentry of OnPaint which would cause wxMemoryDC errors.
116 for ( wxNode
*node
= m_tools
.First(); node
; node
= node
->Next() )
118 wxToolBarTool
*tool
= (wxToolBarTool
*)node
->Data();
119 if (tool
->m_toolStyle
== wxTOOL_STYLE_BUTTON
)
120 DrawTool(dc
, mem_dc
, tool
);
126 void wxToolBarSimple::OnSize ( wxSizeEvent
& event
)
128 wxToolBarBase::OnSize(event
);
131 void wxToolBarSimple::OnKillFocus (wxFocusEvent
& event
)
133 OnMouseEnter(m_pressedTool
= m_currentTool
= -1);
136 void wxToolBarSimple::OnMouseEvent ( wxMouseEvent
& event
)
139 event
.Position(&x
, &y
);
140 wxToolBarTool
*tool
= FindToolForPosition(x
, y
);
144 if (m_currentTool
> -1)
146 if (event
.LeftIsDown())
147 SpringUpButton(m_currentTool
);
154 if (!event
.IsButton())
156 if (tool
->m_index
!= m_currentTool
)
158 // If the left button is kept down and moved over buttons,
159 // press those buttons.
160 if (event
.LeftIsDown() && tool
->m_enabled
) {
161 SpringUpButton(m_currentTool
);
162 tool
->m_toggleState
= !tool
->m_toggleState
;
163 wxMemoryDC
*dc2
= new wxMemoryDC
;
165 DrawTool(dc
, *dc2
, tool
);
168 OnMouseEnter(tool
->m_index
);
169 m_currentTool
= tool
->m_index
;
174 // Left button pressed.
175 if (event
.LeftDown() && tool
->m_enabled
)
177 tool
->m_toggleState
= !tool
->m_toggleState
;
178 wxMemoryDC
*dc2
= new wxMemoryDC
;
180 DrawTool(dc
, *dc2
, tool
);
183 else if (event
.RightDown())
185 OnRightClick(tool
->m_index
, x
, y
);
187 // Left Button Released. Only this action confirms selection.
188 // If the button is enabled and it is not a toggle tool and it is
189 // in the pressed state, then raise the button and call OnLeftClick.
191 if (event
.LeftUp() && tool
->m_enabled
&&
192 (tool
->m_toggleState
|| tool
->m_isToggle
)){
193 if (!tool
->m_isToggle
)
194 tool
->m_toggleState
= FALSE
;
195 // Pass the OnLeftClick event to tool
196 if (!OnLeftClick(tool
->m_index
, tool
->m_toggleState
) && tool
->m_isToggle
)
197 // If it was a toggle, and OnLeftClick says No Toggle allowed,
198 // then change it back
199 tool
->m_toggleState
= !tool
->m_toggleState
;
201 wxMemoryDC
*dc2
= new wxMemoryDC
;
202 DrawTool(dc
, *dc2
, tool
);
207 void wxToolBarSimple::DrawTool(wxDC
& dc
, wxMemoryDC
& memDC
, wxToolBarTool
*tool
)
211 wxBitmap
*bitmap
= tool
->m_toggleState
? (& tool
->m_bitmap2
) : (& tool
->m_bitmap1
);
213 if (bitmap
&& bitmap
->Ok())
215 if (bitmap
->GetColourMap())
216 memDC
.SetPalette(*bitmap
->GetColourMap());
218 int ax
= (int)tool
->m_x
,
220 bx
= (int)(tool
->m_x
+tool
->GetWidth()),
221 by
= (int)(tool
->m_y
+tool
->GetHeight());
223 memDC
.SelectObject(*bitmap
);
224 if (m_windowStyle
& wxTB_3DBUTTONS
)
226 dc
.SetClippingRegion(ax
, ay
, (bx
-ax
+1), (by
-ay
+1));
227 dc
.Blit((ax
+1), (ay
+1), (bx
-ax
-2), (by
-ay
-2), &memDC
, 0, 0);
228 wxPen
* old_pen
= dc
.GetPen();
229 dc
.SetPen( *white_pen
);
230 dc
.DrawLine(ax
,(by
-1),ax
,ay
);
231 dc
.DrawLine(ax
,ay
,(bx
-1),ay
);
232 dc
.SetPen( *dark_grey_pen
);
233 dc
.DrawLine((bx
-1),(ay
+1),(bx
-1),(by
-1));
234 dc
.DrawLine((bx
-1),(by
-1),(ax
+1),(by
-1));
235 dc
.SetPen( *black_pen
);
236 dc
.DrawLine(bx
,ay
,bx
,by
);
237 dc
.DrawLine(bx
,by
,ax
,by
);
238 dc
.SetPen( *old_pen
);
239 dc
.DestroyClippingRegion();
240 // Select bitmap out of the DC
244 dc
.Blit(tool
->m_x
, tool
->m_y
,
245 bitmap
->GetWidth(), bitmap
->GetHeight(),
248 memDC
.SelectObject(wxNullBitmap
);
249 memDC
.SetPalette(wxNullPalette
);
251 // No second bitmap, so draw a thick line around bitmap, or invert if mono
252 else if (tool
->m_toggleState
)
254 bool drawBorder
= FALSE
;
255 #ifdef __X__ // X doesn't invert properly on colour
256 drawBorder
= wxColourDisplay();
257 #else // Inversion works fine under Windows
263 memDC
.SelectObject(tool
->m_bitmap1
);
264 dc
.Blit(tool
->m_x
, tool
->m_y
, tool
->GetWidth(), tool
->GetHeight(),
265 &memDC
, 0, 0, wxSRC_INVERT
);
266 memDC
.SelectObject(wxNullBitmap
);
270 if (m_windowStyle
& wxTB_3DBUTTONS
)
272 int ax
= (int)tool
->m_x
,
274 bx
= (int)(tool
->m_x
+tool
->GetWidth()),
275 by
= (int)(tool
->m_y
+tool
->GetHeight());
277 memDC
.SelectObject(tool
->m_bitmap1
);
278 dc
.SetClippingRegion(ax
, ay
, (bx
-ax
+1), (by
-ay
+1));
279 dc
.Blit((ax
+2), (ay
+2), (bx
-ax
-2), (by
-ay
-2), &memDC
, 0, 0);
280 wxPen
* old_pen
= dc
.GetPen();
281 dc
.SetPen( *black_pen
);
282 dc
.DrawLine(ax
,(by
-1),ax
,ay
);
283 dc
.DrawLine(ax
,ay
,(bx
-1),ay
);
284 dc
.SetPen( *dark_grey_pen
);
285 dc
.DrawLine((ax
+1),(by
-2),(ax
+1),(ay
+1));
286 dc
.DrawLine((ax
+1),(ay
+1),(bx
-2),(ay
+1));
287 dc
.SetPen( *white_pen
);
288 dc
.DrawLine(bx
,ay
,bx
,by
);
289 dc
.DrawLine(bx
,by
,ax
,by
);
290 dc
.SetPen( *old_pen
);
291 dc
.DestroyClippingRegion();
292 memDC
.SelectObject(wxNullBitmap
);
298 long w
= tool
->m_bitmap1
.GetWidth();
299 long h
= tool
->m_bitmap1
.GetHeight();
301 memDC
.SelectObject(tool
->m_bitmap1
);
302 dc
.SetClippingRegion(tool
->m_x
, tool
->m_y
, w
, h
);
303 dc
.Blit(tool
->m_x
, tool
->m_y
, w
, h
,
305 dc
.SetPen(*thick_black_pen
);
306 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
307 dc
.DrawRectangle(x
, y
, w
-1, h
-1);
308 dc
.DestroyClippingRegion();
309 memDC
.SelectObject(wxNullBitmap
);
315 void wxToolBarSimple::ToggleTool(int index
, bool toggle
)
317 wxNode
*node
= m_tools
.Find((long)index
);
320 wxToolBarTool
*tool
= (wxToolBarTool
*)node
->Data();
321 if (tool
&& tool
->m_isToggle
)
323 bool oldState
= tool
->m_toggleState
;
324 tool
->m_toggleState
= toggle
;
326 if (oldState
!= toggle
)
330 DrawTool(dc
, memDC
, tool
);
336 // Okay, so we've left the tool we're in ... we must check if
337 // the tool we're leaving was a 'sprung push button' and if so,
338 // spring it back to the up state.
340 void wxToolBarSimple::SpringUpButton(int index
)
342 wxNode
*node
=m_tools
.Find((long)index
);
344 wxToolBarTool
*tool
= (wxToolBarTool
*)node
->Data();
345 if (tool
&& !tool
->m_isToggle
&& tool
->m_toggleState
){
346 tool
->m_toggleState
= FALSE
;
349 DrawTool(dc
, memDC
, tool
);
351 else if (tool
&& tool
->m_isToggle
){
352 tool
->m_toggleState
= !tool
->m_toggleState
;
355 DrawTool(dc
, memDC
, tool
);
360 void wxToolBarSimple::Layout(void)
362 m_currentRowsOrColumns
= 0;
365 int maxToolWidth
= 0;
366 int maxToolHeight
= 0;
370 // Find the maximum tool width and height
371 wxNode
*node
= m_tools
.First();
374 wxToolBarTool
*tool
= (wxToolBarTool
*)node
->Data();
375 if (tool
->GetWidth() > maxToolWidth
)
376 maxToolWidth
= (int)tool
->GetWidth();
377 if (tool
->GetHeight() > maxToolHeight
)
378 maxToolHeight
= (int)tool
->GetHeight();
382 int separatorSize
= m_toolSeparation
;
384 node
= m_tools
.First();
387 wxToolBarTool
*tool
= (wxToolBarTool
*)node
->Data();
388 if (tool
->m_toolStyle
== wxTOOL_STYLE_SEPARATOR
)
390 if ( GetWindowStyleFlag() & wxTB_HORIZONTAL
)
392 if (m_currentRowsOrColumns
>= m_maxCols
)
393 m_lastY
+= separatorSize
;
395 m_lastX
+= separatorSize
;
399 if (m_currentRowsOrColumns
>= m_maxRows
)
400 m_lastX
+= separatorSize
;
402 m_lastY
+= separatorSize
;
405 else if (tool
->m_toolStyle
== wxTOOL_STYLE_BUTTON
)
407 if ( GetWindowStyleFlag() & wxTB_HORIZONTAL
)
409 if (m_currentRowsOrColumns
>= m_maxCols
)
411 m_currentRowsOrColumns
= 0;
413 m_lastY
+= maxToolHeight
+ m_toolPacking
;
415 tool
->m_x
= (long) (m_lastX
+ (maxToolWidth
- tool
->GetWidth())/2.0);
416 tool
->m_y
= (long) (m_lastY
+ (maxToolHeight
- tool
->GetHeight())/2.0);
418 m_lastX
+= maxToolWidth
+ m_toolPacking
;
422 if (m_currentRowsOrColumns
>= m_maxRows
)
424 m_currentRowsOrColumns
= 0;
425 m_lastX
+= (maxToolWidth
+ m_toolPacking
);
428 tool
->m_x
= (long) (m_lastX
+ (maxToolWidth
- tool
->GetWidth())/2.0);
429 tool
->m_y
= (long) (m_lastY
+ (maxToolHeight
- tool
->GetHeight())/2.0);
431 m_lastY
+= maxToolHeight
+ m_toolPacking
;
433 m_currentRowsOrColumns
++;
436 if (m_lastX
> m_maxWidth
)
437 m_maxWidth
= m_lastX
;
438 if (m_lastY
> m_maxHeight
)
439 m_maxHeight
= m_lastY
;
443 if ( GetWindowStyleFlag() & wxTB_HORIZONTAL
)
444 m_maxWidth
+= maxToolWidth
;
446 m_maxHeight
+= maxToolHeight
;
448 m_maxWidth
+= m_xMargin
;
449 m_maxHeight
+= m_yMargin
;