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"
24 #include "wx/settings.h"
25 #include "wx/window.h"
26 #include "wx/dcclient.h"
27 #include "wx/dcmemory.h"
32 #include "wx/tbarsmpl.h"
34 #if !USE_SHARED_LIBRARY
35 IMPLEMENT_DYNAMIC_CLASS(wxToolBarSimple
, wxToolBarBase
)
37 BEGIN_EVENT_TABLE(wxToolBarSimple
, wxToolBarBase
)
38 EVT_SIZE(wxToolBarSimple::OnSize
)
39 EVT_PAINT(wxToolBarSimple::OnPaint
)
40 EVT_KILL_FOCUS(wxToolBarSimple::OnKillFocus
)
41 EVT_MOUSE_EVENTS(wxToolBarSimple::OnMouseEvent
)
45 wxToolBarSimple::wxToolBarSimple(void)
47 m_currentRowsOrColumns
= 0;
52 bool wxToolBarSimple::Create(wxWindow
*parent
, wxWindowID id
, const wxPoint
& pos
, const wxSize
& size
, long style
,
53 const wxString
& name
)
55 if ( ! wxWindow::Create(parent
, id
, pos
, size
, style
, name
) )
58 // Set it to grey (or other 3D face colour)
59 wxSystemSettings settings
;
60 SetBackgroundColour(settings
.GetSystemColour(wxSYS_COLOUR_3DFACE
));
62 if ( GetWindowStyleFlag() & wxTB_VERTICAL
)
63 { m_lastX
= 7; m_lastY
= 3; }
65 { m_lastX
= 3; m_lastY
= 7; }
66 m_maxWidth
= m_maxHeight
= 0;
67 m_pressedTool
= m_currentTool
= -1;
72 SetCursor(*wxSTANDARD_CURSOR
);
77 wxToolBarSimple::~wxToolBarSimple ()
81 void wxToolBarSimple::OnPaint (wxPaintEvent
& WXUNUSED(event
))
87 // Prevent reentry of OnPaint which would cause wxMemoryDC errors.
94 for ( wxNode
*node
= m_tools
.First(); node
; node
= node
->Next() )
96 wxToolBarTool
*tool
= (wxToolBarTool
*)node
->Data();
97 if (tool
->m_toolStyle
== wxTOOL_STYLE_BUTTON
)
98 DrawTool(dc
, mem_dc
, tool
);
104 void wxToolBarSimple::OnSize ( wxSizeEvent
& event
)
106 wxToolBarBase::OnSize(event
);
109 void wxToolBarSimple::OnKillFocus (wxFocusEvent
& WXUNUSED(event
))
111 OnMouseEnter(m_pressedTool
= m_currentTool
= -1);
114 void wxToolBarSimple::OnMouseEvent ( wxMouseEvent
& event
)
117 event
.Position(&x
, &y
);
118 wxToolBarTool
*tool
= FindToolForPosition(x
, y
);
120 if (event
.LeftDown())
131 if (m_currentTool
> -1)
133 if (event
.LeftIsDown())
134 SpringUpButton(m_currentTool
);
141 if (!event
.IsButton())
143 if (tool
->m_index
!= m_currentTool
)
145 // If the left button is kept down and moved over buttons,
146 // press those buttons.
147 if (event
.LeftIsDown() && tool
->m_enabled
)
149 SpringUpButton(m_currentTool
);
150 tool
->m_toggleState
= !tool
->m_toggleState
;
151 wxMemoryDC
*dc2
= new wxMemoryDC
;
153 DrawTool(dc
, *dc2
, tool
);
156 m_currentTool
= tool
->m_index
;
157 OnMouseEnter(tool
->m_index
);
162 // Left button pressed.
163 if (event
.LeftDown() && tool
->m_enabled
)
165 if (tool
->m_isToggle
)
167 tool
->m_toggleState
= !tool
->m_toggleState
;
170 wxMemoryDC
*dc2
= new wxMemoryDC
;
172 DrawTool(dc
, *dc2
, tool
);
176 else if (event
.RightDown())
178 OnRightClick(tool
->m_index
, x
, y
);
181 // Left Button Released. Only this action confirms selection.
182 // If the button is enabled and it is not a toggle tool and it is
183 // in the pressed state, then raise the button and call OnLeftClick.
185 if (event
.LeftUp() && tool
->m_enabled
&&
186 (tool
->m_toggleState
|| tool
->m_isToggle
))
188 if (!tool
->m_isToggle
)
189 tool
->m_toggleState
= FALSE
;
191 // Pass the OnLeftClick event to tool
192 if (!OnLeftClick(tool
->m_index
, tool
->m_toggleState
) && tool
->m_isToggle
)
194 // If it was a toggle, and OnLeftClick says No Toggle allowed,
195 // then change it back
196 tool
->m_toggleState
= !tool
->m_toggleState
;
200 wxMemoryDC
*dc2
= new wxMemoryDC
;
201 DrawTool(dc
, *dc2
, tool
);
206 void wxToolBarSimple::DrawTool(wxDC
& dc
, wxMemoryDC
& memDC
, wxToolBarTool
*tool
)
210 wxPen
dark_grey_pen(wxColour( 85,85,85 ), 1, wxSOLID
);
211 wxPen
white_pen("WHITE", 1, wxSOLID
);
212 wxPen
black_pen("BLACK", 1, wxSOLID
);
214 wxBitmap
*bitmap
= tool
->m_toggleState
? (& tool
->m_bitmap2
) : (& tool
->m_bitmap1
);
216 if (bitmap
&& bitmap
->Ok())
219 if (bitmap
->GetPalette())
220 memDC
.SetPalette(*bitmap
->GetPalette());
223 int ax
= (int)tool
->m_x
,
225 bx
= (int)(tool
->m_x
+tool
->GetWidth()),
226 by
= (int)(tool
->m_y
+tool
->GetHeight());
228 memDC
.SelectObject(*bitmap
);
229 if (m_windowStyle
& wxTB_3DBUTTONS
)
231 dc
.SetClippingRegion(ax
, ay
, (bx
-ax
+1), (by
-ay
+1));
232 dc
.Blit((ax
+1), (ay
+1), (bx
-ax
-2), (by
-ay
-2), &memDC
, 0, 0);
233 wxPen
* old_pen
= & dc
.GetPen();
234 dc
.SetPen( white_pen
);
235 dc
.DrawLine(ax
,(by
-1),ax
,ay
);
236 dc
.DrawLine(ax
,ay
,(bx
-1),ay
);
237 dc
.SetPen( dark_grey_pen
);
238 dc
.DrawLine((bx
-1),(ay
+1),(bx
-1),(by
-1));
239 dc
.DrawLine((bx
-1),(by
-1),(ax
+1),(by
-1));
240 dc
.SetPen( black_pen
);
241 dc
.DrawLine(bx
,ay
,bx
,by
);
242 dc
.DrawLine(bx
,by
,ax
,by
);
243 dc
.SetPen( *old_pen
);
244 dc
.DestroyClippingRegion();
245 // Select bitmap out of the DC
249 dc
.Blit(tool
->m_x
, tool
->m_y
,
250 bitmap
->GetWidth(), bitmap
->GetHeight(),
253 memDC
.SelectObject(wxNullBitmap
);
255 memDC
.SetPalette(wxNullPalette
);
258 // No second bitmap, so draw a thick line around bitmap, or invert if mono
259 else if (tool
->m_toggleState
)
261 bool drawBorder
= FALSE
;
262 #ifdef __X__ // X doesn't invert properly on colour
263 drawBorder
= wxColourDisplay();
264 #else // Inversion works fine under Windows
270 memDC
.SelectObject(tool
->m_bitmap1
);
271 dc
.Blit(tool
->m_x
, tool
->m_y
, tool
->GetWidth(), tool
->GetHeight(),
272 &memDC
, 0, 0, wxSRC_INVERT
);
273 memDC
.SelectObject(wxNullBitmap
);
277 if (m_windowStyle
& wxTB_3DBUTTONS
)
279 int ax
= (int)tool
->m_x
,
281 bx
= (int)(tool
->m_x
+tool
->GetWidth()),
282 by
= (int)(tool
->m_y
+tool
->GetHeight());
284 memDC
.SelectObject(tool
->m_bitmap1
);
285 dc
.SetClippingRegion(ax
, ay
, (bx
-ax
+1), (by
-ay
+1));
286 dc
.Blit((ax
+2), (ay
+2), (bx
-ax
-2), (by
-ay
-2), &memDC
, 0, 0);
287 wxPen
* old_pen
= & dc
.GetPen();
288 dc
.SetPen( black_pen
);
289 dc
.DrawLine(ax
,(by
-1),ax
,ay
);
290 dc
.DrawLine(ax
,ay
,(bx
-1),ay
);
291 dc
.SetPen( dark_grey_pen
);
292 dc
.DrawLine((ax
+1),(by
-2),(ax
+1),(ay
+1));
293 dc
.DrawLine((ax
+1),(ay
+1),(bx
-2),(ay
+1));
294 dc
.SetPen( white_pen
);
295 dc
.DrawLine(bx
,ay
,bx
,by
);
296 dc
.DrawLine(bx
,by
,ax
,by
);
297 dc
.SetPen( *old_pen
);
298 dc
.DestroyClippingRegion();
299 memDC
.SelectObject(wxNullBitmap
);
305 long w
= tool
->m_bitmap1
.GetWidth();
306 long h
= tool
->m_bitmap1
.GetHeight();
307 wxPen
thick_black_pen("BLACK", 3, wxSOLID
);
309 memDC
.SelectObject(tool
->m_bitmap1
);
310 dc
.SetClippingRegion(tool
->m_x
, tool
->m_y
, w
, h
);
311 dc
.Blit(tool
->m_x
, tool
->m_y
, w
, h
,
313 dc
.SetPen(thick_black_pen
);
314 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
315 dc
.DrawRectangle(x
, y
, w
-1, h
-1);
316 dc
.DestroyClippingRegion();
317 memDC
.SelectObject(wxNullBitmap
);
323 void wxToolBarSimple::ToggleTool(int index
, bool toggle
)
325 wxNode
*node
= (wxNode
*) NULL
;
326 node
= m_tools
.Find((long)index
);
329 wxToolBarTool
*tool
= (wxToolBarTool
*)node
->Data();
330 if (tool
&& tool
->m_isToggle
)
332 bool oldState
= tool
->m_toggleState
;
333 tool
->m_toggleState
= toggle
;
335 if (oldState
!= toggle
)
339 DrawTool(dc
, memDC
, tool
);
345 // Okay, so we've left the tool we're in ... we must check if
346 // the tool we're leaving was a 'sprung push button' and if so,
347 // spring it back to the up state.
349 void wxToolBarSimple::SpringUpButton(int index
)
351 wxNode
*node
= (wxNode
*) NULL
;
352 node
=m_tools
.Find((long)index
);
354 wxToolBarTool
*tool
= (wxToolBarTool
*)node
->Data();
355 if (tool
&& !tool
->m_isToggle
&& tool
->m_toggleState
){
356 tool
->m_toggleState
= FALSE
;
359 DrawTool(dc
, memDC
, tool
);
361 else if (tool
&& tool
->m_isToggle
){
362 tool
->m_toggleState
= !tool
->m_toggleState
;
365 DrawTool(dc
, memDC
, tool
);
370 void wxToolBarSimple::LayoutTools(void)
372 m_currentRowsOrColumns
= 0;
375 int maxToolWidth
= 0;
376 int maxToolHeight
= 0;
380 // Find the maximum tool width and height
381 wxNode
*node
= m_tools
.First();
384 wxToolBarTool
*tool
= (wxToolBarTool
*)node
->Data();
385 if (tool
->GetWidth() > maxToolWidth
)
386 maxToolWidth
= (int)tool
->GetWidth();
387 if (tool
->GetHeight() > maxToolHeight
)
388 maxToolHeight
= (int)tool
->GetHeight();
392 int separatorSize
= m_toolSeparation
;
394 node
= m_tools
.First();
397 wxToolBarTool
*tool
= (wxToolBarTool
*)node
->Data();
398 if (tool
->m_toolStyle
== wxTOOL_STYLE_SEPARATOR
)
400 if ( GetWindowStyleFlag() & wxTB_HORIZONTAL
)
402 if (m_currentRowsOrColumns
>= m_maxCols
)
403 m_lastY
+= separatorSize
;
405 m_lastX
+= separatorSize
;
409 if (m_currentRowsOrColumns
>= m_maxRows
)
410 m_lastX
+= separatorSize
;
412 m_lastY
+= separatorSize
;
415 else if (tool
->m_toolStyle
== wxTOOL_STYLE_BUTTON
)
417 if ( GetWindowStyleFlag() & wxTB_HORIZONTAL
)
419 if (m_currentRowsOrColumns
>= m_maxCols
)
421 m_currentRowsOrColumns
= 0;
423 m_lastY
+= maxToolHeight
+ m_toolPacking
;
425 tool
->m_x
= (long) (m_lastX
+ (maxToolWidth
- tool
->GetWidth())/2.0);
426 tool
->m_y
= (long) (m_lastY
+ (maxToolHeight
- tool
->GetHeight())/2.0);
428 m_lastX
+= maxToolWidth
+ m_toolPacking
;
432 if (m_currentRowsOrColumns
>= m_maxRows
)
434 m_currentRowsOrColumns
= 0;
435 m_lastX
+= (maxToolWidth
+ m_toolPacking
);
438 tool
->m_x
= (long) (m_lastX
+ (maxToolWidth
- tool
->GetWidth())/2.0);
439 tool
->m_y
= (long) (m_lastY
+ (maxToolHeight
- tool
->GetHeight())/2.0);
441 m_lastY
+= maxToolHeight
+ m_toolPacking
;
443 m_currentRowsOrColumns
++;
446 if (m_lastX
> m_maxWidth
)
447 m_maxWidth
= m_lastX
;
448 if (m_lastY
> m_maxHeight
)
449 m_maxHeight
= m_lastY
;
453 if ( GetWindowStyleFlag() & wxTB_HORIZONTAL
)
454 m_maxWidth
+= maxToolWidth
;
456 m_maxHeight
+= maxToolHeight
;
458 m_maxWidth
+= m_xMargin
;
459 m_maxHeight
+= m_yMargin
;