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 IMPLEMENT_DYNAMIC_CLASS(wxToolBarSimple
, wxToolBarBase
)
36 BEGIN_EVENT_TABLE(wxToolBarSimple
, wxToolBarBase
)
37 EVT_SIZE(wxToolBarSimple::OnSize
)
38 EVT_PAINT(wxToolBarSimple::OnPaint
)
39 EVT_KILL_FOCUS(wxToolBarSimple::OnKillFocus
)
40 EVT_MOUSE_EVENTS(wxToolBarSimple::OnMouseEvent
)
43 wxToolBarSimple::wxToolBarSimple(void)
45 m_currentRowsOrColumns
= 0;
50 bool wxToolBarSimple::Create(wxWindow
*parent
, wxWindowID id
, const wxPoint
& pos
, const wxSize
& size
, long style
,
51 const wxString
& name
)
53 if ( ! wxWindow::Create(parent
, id
, pos
, size
, style
, name
) )
56 // Set it to grey (or other 3D face colour)
57 wxSystemSettings settings
;
58 SetBackgroundColour(settings
.GetSystemColour(wxSYS_COLOUR_3DFACE
));
60 if ( GetWindowStyleFlag() & wxTB_VERTICAL
)
61 { m_lastX
= 7; m_lastY
= 3; }
63 { m_lastX
= 3; m_lastY
= 7; }
64 m_maxWidth
= m_maxHeight
= 0;
65 m_pressedTool
= m_currentTool
= -1;
70 SetCursor(*wxSTANDARD_CURSOR
);
75 wxToolBarSimple::~wxToolBarSimple ()
79 void wxToolBarSimple::OnPaint (wxPaintEvent
& WXUNUSED(event
))
85 // Prevent reentry of OnPaint which would cause wxMemoryDC errors.
92 for ( wxNode
*node
= m_tools
.First(); node
; node
= node
->Next() )
94 wxToolBarTool
*tool
= (wxToolBarTool
*)node
->Data();
95 if (tool
->m_toolStyle
== wxTOOL_STYLE_BUTTON
)
96 DrawTool(dc
, mem_dc
, tool
);
102 void wxToolBarSimple::OnSize ( wxSizeEvent
& event
)
104 wxToolBarBase::OnSize(event
);
107 void wxToolBarSimple::OnKillFocus (wxFocusEvent
& WXUNUSED(event
))
109 OnMouseEnter(m_pressedTool
= m_currentTool
= -1);
112 void wxToolBarSimple::OnMouseEvent ( wxMouseEvent
& event
)
115 event
.GetPosition(&x
, &y
);
116 wxToolBarTool
*tool
= FindToolForPosition(x
, y
);
118 if (event
.LeftDown())
129 if (m_currentTool
> -1)
131 if (event
.LeftIsDown())
132 SpringUpButton(m_currentTool
);
139 if (!event
.IsButton())
141 if (tool
->m_index
!= m_currentTool
)
143 // If the left button is kept down and moved over buttons,
144 // press those buttons.
145 if (event
.LeftIsDown() && tool
->m_enabled
)
147 SpringUpButton(m_currentTool
);
148 tool
->m_toggleState
= !tool
->m_toggleState
;
149 wxMemoryDC
*dc2
= new wxMemoryDC
;
151 DrawTool(dc
, *dc2
, tool
);
154 m_currentTool
= tool
->m_index
;
155 OnMouseEnter(tool
->m_index
);
160 // Left button pressed.
161 if (event
.LeftDown() && tool
->m_enabled
)
163 if (tool
->m_isToggle
)
165 tool
->m_toggleState
= !tool
->m_toggleState
;
168 wxMemoryDC
*dc2
= new wxMemoryDC
;
170 DrawTool(dc
, *dc2
, tool
);
174 else if (event
.RightDown())
176 OnRightClick(tool
->m_index
, x
, y
);
179 // Left Button Released. Only this action confirms selection.
180 // If the button is enabled and it is not a toggle tool and it is
181 // in the pressed state, then raise the button and call OnLeftClick.
183 if (event
.LeftUp() && tool
->m_enabled
&&
184 (tool
->m_toggleState
|| tool
->m_isToggle
))
186 if (!tool
->m_isToggle
)
187 tool
->m_toggleState
= FALSE
;
189 // Pass the OnLeftClick event to tool
190 if (!OnLeftClick(tool
->m_index
, tool
->m_toggleState
) && tool
->m_isToggle
)
192 // If it was a toggle, and OnLeftClick says No Toggle allowed,
193 // then change it back
194 tool
->m_toggleState
= !tool
->m_toggleState
;
198 wxMemoryDC
*dc2
= new wxMemoryDC
;
199 DrawTool(dc
, *dc2
, tool
);
204 void wxToolBarSimple::DrawTool(wxDC
& dc
, wxMemoryDC
& memDC
, wxToolBarTool
*tool
)
208 wxPen
dark_grey_pen(wxColour( 85,85,85 ), 1, wxSOLID
);
209 wxPen
white_pen("WHITE", 1, wxSOLID
);
210 wxPen
black_pen("BLACK", 1, wxSOLID
);
212 wxBitmap
*bitmap
= tool
->m_toggleState
? (& tool
->m_bitmap2
) : (& tool
->m_bitmap1
);
214 if (bitmap
&& bitmap
->Ok())
217 if (bitmap
->GetPalette())
218 memDC
.SetPalette(*bitmap
->GetPalette());
221 int ax
= (int)tool
->m_x
,
223 bx
= (int)(tool
->m_x
+tool
->GetWidth()),
224 by
= (int)(tool
->m_y
+tool
->GetHeight());
226 memDC
.SelectObject(*bitmap
);
227 if (m_windowStyle
& wxTB_3DBUTTONS
)
229 dc
.SetClippingRegion(ax
, ay
, (bx
-ax
+1), (by
-ay
+1));
230 dc
.Blit((ax
+1), (ay
+1), (bx
-ax
-2), (by
-ay
-2), &memDC
, 0, 0);
231 wxPen
* old_pen
= & dc
.GetPen();
232 dc
.SetPen( white_pen
);
233 dc
.DrawLine(ax
,(by
-1),ax
,ay
);
234 dc
.DrawLine(ax
,ay
,(bx
-1),ay
);
235 dc
.SetPen( dark_grey_pen
);
236 dc
.DrawLine((bx
-1),(ay
+1),(bx
-1),(by
-1));
237 dc
.DrawLine((bx
-1),(by
-1),(ax
+1),(by
-1));
238 dc
.SetPen( black_pen
);
239 dc
.DrawLine(bx
,ay
,bx
,by
);
240 dc
.DrawLine(bx
,by
,ax
,by
);
241 dc
.SetPen( *old_pen
);
242 dc
.DestroyClippingRegion();
243 // Select bitmap out of the DC
247 dc
.Blit(tool
->m_x
, tool
->m_y
,
248 bitmap
->GetWidth(), bitmap
->GetHeight(),
251 memDC
.SelectObject(wxNullBitmap
);
253 memDC
.SetPalette(wxNullPalette
);
256 // No second bitmap, so draw a thick line around bitmap, or invert if mono
257 else if (tool
->m_toggleState
)
259 bool drawBorder
= FALSE
;
260 #ifdef __X__ // X doesn't invert properly on colour
261 drawBorder
= wxColourDisplay();
262 #else // Inversion works fine under Windows
268 memDC
.SelectObject(tool
->m_bitmap1
);
269 dc
.Blit(tool
->m_x
, tool
->m_y
, tool
->GetWidth(), tool
->GetHeight(),
270 &memDC
, 0, 0, wxSRC_INVERT
);
271 memDC
.SelectObject(wxNullBitmap
);
275 if (m_windowStyle
& wxTB_3DBUTTONS
)
277 int ax
= (int)tool
->m_x
,
279 bx
= (int)(tool
->m_x
+tool
->GetWidth()),
280 by
= (int)(tool
->m_y
+tool
->GetHeight());
282 memDC
.SelectObject(tool
->m_bitmap1
);
283 dc
.SetClippingRegion(ax
, ay
, (bx
-ax
+1), (by
-ay
+1));
284 dc
.Blit((ax
+2), (ay
+2), (bx
-ax
-2), (by
-ay
-2), &memDC
, 0, 0);
285 wxPen
* old_pen
= & dc
.GetPen();
286 dc
.SetPen( black_pen
);
287 dc
.DrawLine(ax
,(by
-1),ax
,ay
);
288 dc
.DrawLine(ax
,ay
,(bx
-1),ay
);
289 dc
.SetPen( dark_grey_pen
);
290 dc
.DrawLine((ax
+1),(by
-2),(ax
+1),(ay
+1));
291 dc
.DrawLine((ax
+1),(ay
+1),(bx
-2),(ay
+1));
292 dc
.SetPen( white_pen
);
293 dc
.DrawLine(bx
,ay
,bx
,by
);
294 dc
.DrawLine(bx
,by
,ax
,by
);
295 dc
.SetPen( *old_pen
);
296 dc
.DestroyClippingRegion();
297 memDC
.SelectObject(wxNullBitmap
);
303 long w
= tool
->m_bitmap1
.GetWidth();
304 long h
= tool
->m_bitmap1
.GetHeight();
305 wxPen
thick_black_pen("BLACK", 3, wxSOLID
);
307 memDC
.SelectObject(tool
->m_bitmap1
);
308 dc
.SetClippingRegion(tool
->m_x
, tool
->m_y
, w
, h
);
309 dc
.Blit(tool
->m_x
, tool
->m_y
, w
, h
,
311 dc
.SetPen(thick_black_pen
);
312 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
313 dc
.DrawRectangle(x
, y
, w
-1, h
-1);
314 dc
.DestroyClippingRegion();
315 memDC
.SelectObject(wxNullBitmap
);
321 void wxToolBarSimple::ToggleTool(int index
, bool toggle
)
323 wxNode
*node
= (wxNode
*) NULL
;
324 node
= m_tools
.Find((long)index
);
327 wxToolBarTool
*tool
= (wxToolBarTool
*)node
->Data();
328 if (tool
&& tool
->m_isToggle
)
330 bool oldState
= tool
->m_toggleState
;
331 tool
->m_toggleState
= toggle
;
333 if (oldState
!= toggle
)
337 DrawTool(dc
, memDC
, tool
);
343 // Okay, so we've left the tool we're in ... we must check if
344 // the tool we're leaving was a 'sprung push button' and if so,
345 // spring it back to the up state.
347 void wxToolBarSimple::SpringUpButton(int index
)
349 wxNode
*node
= (wxNode
*) NULL
;
350 node
=m_tools
.Find((long)index
);
352 wxToolBarTool
*tool
= (wxToolBarTool
*)node
->Data();
353 if (tool
&& !tool
->m_isToggle
&& tool
->m_toggleState
){
354 tool
->m_toggleState
= FALSE
;
357 DrawTool(dc
, memDC
, tool
);
359 else if (tool
&& tool
->m_isToggle
){
360 tool
->m_toggleState
= !tool
->m_toggleState
;
363 DrawTool(dc
, memDC
, tool
);
368 void wxToolBarSimple::LayoutTools(void)
370 m_currentRowsOrColumns
= 0;
373 int maxToolWidth
= 0;
374 int maxToolHeight
= 0;
378 // Find the maximum tool width and height
379 wxNode
*node
= m_tools
.First();
382 wxToolBarTool
*tool
= (wxToolBarTool
*)node
->Data();
383 if (tool
->GetWidth() > maxToolWidth
)
384 maxToolWidth
= (int)tool
->GetWidth();
385 if (tool
->GetHeight() > maxToolHeight
)
386 maxToolHeight
= (int)tool
->GetHeight();
390 int separatorSize
= m_toolSeparation
;
392 node
= m_tools
.First();
395 wxToolBarTool
*tool
= (wxToolBarTool
*)node
->Data();
396 if (tool
->m_toolStyle
== wxTOOL_STYLE_SEPARATOR
)
398 if ( GetWindowStyleFlag() & wxTB_HORIZONTAL
)
400 if (m_currentRowsOrColumns
>= m_maxCols
)
401 m_lastY
+= separatorSize
;
403 m_lastX
+= separatorSize
;
407 if (m_currentRowsOrColumns
>= m_maxRows
)
408 m_lastX
+= separatorSize
;
410 m_lastY
+= separatorSize
;
413 else if (tool
->m_toolStyle
== wxTOOL_STYLE_BUTTON
)
415 if ( GetWindowStyleFlag() & wxTB_HORIZONTAL
)
417 if (m_currentRowsOrColumns
>= m_maxCols
)
419 m_currentRowsOrColumns
= 0;
421 m_lastY
+= maxToolHeight
+ m_toolPacking
;
423 tool
->m_x
= (long) (m_lastX
+ (maxToolWidth
- tool
->GetWidth())/2.0);
424 tool
->m_y
= (long) (m_lastY
+ (maxToolHeight
- tool
->GetHeight())/2.0);
426 m_lastX
+= maxToolWidth
+ m_toolPacking
;
430 if (m_currentRowsOrColumns
>= m_maxRows
)
432 m_currentRowsOrColumns
= 0;
433 m_lastX
+= (maxToolWidth
+ m_toolPacking
);
436 tool
->m_x
= (long) (m_lastX
+ (maxToolWidth
- tool
->GetWidth())/2.0);
437 tool
->m_y
= (long) (m_lastY
+ (maxToolHeight
- tool
->GetHeight())/2.0);
439 m_lastY
+= maxToolHeight
+ m_toolPacking
;
441 m_currentRowsOrColumns
++;
444 if (m_lastX
> m_maxWidth
)
445 m_maxWidth
= m_lastX
;
446 if (m_lastY
> m_maxHeight
)
447 m_maxHeight
= m_lastY
;
451 if ( GetWindowStyleFlag() & wxTB_HORIZONTAL
)
452 m_maxWidth
+= maxToolWidth
;
454 m_maxHeight
+= maxToolHeight
;
456 m_maxWidth
+= m_xMargin
;
457 m_maxHeight
+= m_yMargin
;