]> git.saurik.com Git - wxWidgets.git/blame - src/common/tbarsmpl.cpp
Cured problem introduced by LEAVE/ENTER OnIdle code; bugs in gauge sizing
[wxWidgets.git] / src / common / tbarsmpl.cpp
CommitLineData
10b959e3
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: tbarsmpl.cpp
3// Purpose: wxToolBarSimple
4// Author: Julian Smart
5// Modified by:
6// Created: 04/01/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart and Markus Holzem
9// Licence: wxWindows license
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "tbarsmpl.h"
14#endif
15
16// For compilers that support precompilation, includes "wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
20#pragma hdrstop
21#endif
22
23#ifndef WX_PRECOMP
24#include "wx.h"
25#endif
26
27#if USE_TOOLBAR
28
29#include "wx/tbarsmpl.h"
30
31#if !USE_SHARED_LIBRARY
32IMPLEMENT_DYNAMIC_CLASS(wxToolBarSimple, wxToolBarBase)
33
34BEGIN_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)
39END_EVENT_TABLE()
40#endif
41
42// TODO: eliminate these; use system colours
43static wxPen * white_pen = NULL,
44 * dark_grey_pen = NULL,
45 * black_pen = NULL,
46 * thick_black_pen;
47
48wxToolBarSimple::wxToolBarSimple(void)
49{
50}
51
52bool wxToolBarSimple::Create(wxWindow *parent, const wxWindowID id, const wxPoint& pos, const wxSize& size, const long style,
53 const int direction, const int RowsOrColumns, const wxString& name )
54{
55 if ( ! wxWindow::Create(parent, id, pos, size, style, name) )
56 return FALSE;
57
58 // Set it to grey (or other 3D face colour)
59 wxSystemSettings settings;
60 SetBackgroundColour(settings.GetSystemColour(wxSYS_COLOUR_3DFACE));
61 SetDefaultBackgroundColour(settings.GetSystemColour(wxSYS_COLOUR_3DFACE));
62
63 if ( white_pen == 0 )
64 {
65 white_pen = new wxPen;
66 white_pen->SetColour( "WHITE" );
67 }
68 if ( dark_grey_pen == 0 )
69 {
70 dark_grey_pen = new wxPen;
71 dark_grey_pen->SetColour( 85,85,85 );
72 }
73 if ( black_pen == 0 )
74 {
75 black_pen = new wxPen;
76 black_pen->SetColour( "BLACK" );
77 }
78 if ( thick_black_pen == 0 )
79 {
80 thick_black_pen = new wxPen("BLACK", 3, wxSOLID);
81 }
82 m_tilingDirection = direction;
83 m_rowsOrColumns = RowsOrColumns;
84 if ( m_tilingDirection == wxVERTICAL )
85 { m_lastX = 3; m_lastY = 7; }
86 else
87 { m_lastX = 7; m_lastY = 3; }
88 m_maxWidth = m_maxHeight = 0;
89 m_pressedTool = m_currentTool = -1;
90 m_xMargin = 0;
91 m_yMargin = 0;
92 m_toolPacking = 1;
93 m_toolSeparation = 5;
94
95 return TRUE;
96}
97
98wxToolBarSimple::~wxToolBarSimple ()
99{
100}
101
102void wxToolBarSimple::OnPaint (wxPaintEvent& event)
103{
104 wxPaintDC dc(this);
105 PrepareDC(dc);
106
107 static int count = 0;
108 // Prevent reentry of OnPaint which would cause wxMemoryDC errors.
109 if ( count > 0 )
110 return;
111 count++;
112
113 wxMemoryDC mem_dc;
114
115 for ( wxNode *node = m_tools.First(); node; node = node->Next() )
116 {
117 wxToolBarTool *tool = (wxToolBarTool *)node->Data();
118 if (tool->m_toolStyle == wxTOOL_STYLE_BUTTON)
119 DrawTool(dc, mem_dc, tool);
120 }
121
122/* Old code which drew a line beneath the toolbar - not generally
123 * wanted.
124 int w, h;
125 GetClientSize( &w, &h );
126 wxPen * old_pen = dc.GetPen();
127 dc.SetPen( *white_pen );
128 dc.DrawLine(0,0,w,0);
129 dc.SetPen( *black_pen );
130 dc.DrawLine(0,(h-1),w,(h-1));
131 dc.SetPen( *old_pen );
132*/
133
134 count--;
135}
136
137void wxToolBarSimple::OnSize ( wxSizeEvent& event )
138{
139 wxToolBarBase::OnSize(event);
140}
141
142void wxToolBarSimple::OnKillFocus (wxFocusEvent& event)
143{
144 OnMouseEnter(m_pressedTool = m_currentTool = -1);
145}
146
147void wxToolBarSimple::OnMouseEvent ( wxMouseEvent & event )
148{
149 long x, y;
150 event.Position(&x, &y);
151 wxToolBarTool *tool = FindToolForPosition(x, y);
152
153 if (!tool)
154 {
155 if (m_currentTool > -1)
156 {
157 if (event.LeftIsDown())
158 SpringUpButton(m_currentTool);
159 m_currentTool = -1;
160 OnMouseEnter(-1);
161 }
162 return;
163 }
164
165 if (!event.IsButton())
166 {
167 if (tool->m_index != m_currentTool)
168 {
169 // If the left button is kept down and moved over buttons,
170 // press those buttons.
171 if (event.LeftIsDown() && tool->m_enabled) {
172 SpringUpButton(m_currentTool);
173 tool->m_toggleState = !tool->m_toggleState;
174 wxMemoryDC *dc2 = new wxMemoryDC;
175 wxClientDC dc(this);
176 DrawTool(dc, *dc2, tool);
177 delete dc2;
178 }
179 OnMouseEnter(tool->m_index);
180 m_currentTool = tool->m_index;
181 }
182 return;
183 }
184
185 // Left button pressed.
186 if (event.LeftDown() && tool->m_enabled)
187 {
188 tool->m_toggleState = !tool->m_toggleState;
189 wxMemoryDC *dc2 = new wxMemoryDC;
190 wxClientDC dc(this);
191 DrawTool(dc, *dc2, tool);
192 delete dc2;
193 }
194 else if (event.RightDown())
195 {
196 OnRightClick(tool->m_index, x, y);
197 }
198 // Left Button Released. Only this action confirms selection.
199 // If the button is enabled and it is not a toggle tool and it is
200 // in the pressed state, then raise the button and call OnLeftClick.
201 //
202 if (event.LeftUp() && tool->m_enabled &&
203 (tool->m_toggleState || tool->m_isToggle)){
204 if (!tool->m_isToggle)
205 tool->m_toggleState = FALSE;
206 // Pass the OnLeftClick event to tool
207 if (!OnLeftClick(tool->m_index, tool->m_toggleState) && tool->m_isToggle)
208 // If it was a toggle, and OnLeftClick says No Toggle allowed,
209 // then change it back
210 tool->m_toggleState = !tool->m_toggleState;
211 wxClientDC dc(this);
212 wxMemoryDC *dc2 = new wxMemoryDC;
213 DrawTool(dc, *dc2, tool);
214 delete dc2;
215 }
216}
217
218void wxToolBarSimple::DrawTool(wxDC& dc, wxMemoryDC& memDC, wxToolBarTool *tool)
219{
220 PrepareDC(dc);
221
222 wxBitmap *bitmap = tool->m_toggleState ? (& tool->m_bitmap2) : (& tool->m_bitmap1);
223
224 if (bitmap && bitmap->Ok())
225 {
226 if (bitmap->GetColourMap())
227 memDC.SetPalette(*bitmap->GetColourMap());
228
229 int ax = (int)tool->m_x,
230 ay = (int)tool->m_y,
231 bx = (int)(tool->m_x+tool->GetWidth()),
232 by = (int)(tool->m_y+tool->GetHeight());
233
234 memDC.SelectObject(*bitmap);
235 if (m_windowStyle & wxTB_3DBUTTONS)
236 {
237 dc.SetClippingRegion(ax, ay, (bx-ax+1), (by-ay+1));
238 dc.Blit((ax+1), (ay+1), (bx-ax-2), (by-ay-2), &memDC, 0, 0);
239 wxPen * old_pen = dc.GetPen();
240 dc.SetPen( *white_pen );
241 dc.DrawLine(ax,(by-1),ax,ay);
242 dc.DrawLine(ax,ay,(bx-1),ay);
243 dc.SetPen( *dark_grey_pen );
244 dc.DrawLine((bx-1),(ay+1),(bx-1),(by-1));
245 dc.DrawLine((bx-1),(by-1),(ax+1),(by-1));
246 dc.SetPen( *black_pen );
247 dc.DrawLine(bx,ay,bx,by);
248 dc.DrawLine(bx,by,ax,by);
249 dc.SetPen( *old_pen );
250 dc.DestroyClippingRegion();
251 // Select bitmap out of the DC
252 }
253 else
254 {
255 dc.Blit(tool->m_x, tool->m_y,
256 bitmap->GetWidth(), bitmap->GetHeight(),
257 &memDC, 0, 0);
258 }
259 memDC.SelectObject(wxNullBitmap);
260 memDC.SetPalette(wxNullPalette);
261 }
262 // No second bitmap, so draw a thick line around bitmap, or invert if mono
263 else if (tool->m_toggleState)
264 {
265 bool drawBorder = FALSE;
266 #ifdef __X__ // X doesn't invert properly on colour
267 drawBorder = wxColourDisplay();
268 #else // Inversion works fine under Windows
269 drawBorder = FALSE;
270 #endif
271
272 if (!drawBorder)
273 {
274 memDC.SelectObject(tool->m_bitmap1);
275 dc.Blit(tool->m_x, tool->m_y, tool->GetWidth(), tool->GetHeight(),
276 &memDC, 0, 0, wxSRC_INVERT);
277 memDC.SelectObject(wxNullBitmap);
278 }
279 else
280 {
281 if (m_windowStyle & wxTB_3DBUTTONS)
282 {
283 int ax = (int)tool->m_x,
284 ay = (int)tool->m_y,
285 bx = (int)(tool->m_x+tool->GetWidth()),
286 by = (int)(tool->m_y+tool->GetHeight());
287
288 memDC.SelectObject(tool->m_bitmap1);
289 dc.SetClippingRegion(ax, ay, (bx-ax+1), (by-ay+1));
290 dc.Blit((ax+2), (ay+2), (bx-ax-2), (by-ay-2), &memDC, 0, 0);
291 wxPen * old_pen = dc.GetPen();
292 dc.SetPen( *black_pen );
293 dc.DrawLine(ax,(by-1),ax,ay);
294 dc.DrawLine(ax,ay,(bx-1),ay);
295 dc.SetPen( *dark_grey_pen );
296 dc.DrawLine((ax+1),(by-2),(ax+1),(ay+1));
297 dc.DrawLine((ax+1),(ay+1),(bx-2),(ay+1));
298 dc.SetPen( *white_pen );
299 dc.DrawLine(bx,ay,bx,by);
300 dc.DrawLine(bx,by,ax,by);
301 dc.SetPen( *old_pen );
302 dc.DestroyClippingRegion();
303 memDC.SelectObject(wxNullBitmap);
304 }
305 else
306 {
307 long x = tool->m_x;
308 long y = tool->m_y;
309 long w = tool->m_bitmap1.GetWidth();
310 long h = tool->m_bitmap1.GetHeight();
311
312 memDC.SelectObject(tool->m_bitmap1);
313 dc.SetClippingRegion(tool->m_x, tool->m_y, w, h);
314 dc.Blit(tool->m_x, tool->m_y, w, h,
315 &memDC, 0, 0);
316 dc.SetPen(*thick_black_pen);
317 dc.SetBrush(*wxTRANSPARENT_BRUSH);
318 dc.DrawRectangle(x, y, w-1, h-1);
319 dc.DestroyClippingRegion();
320 memDC.SelectObject(wxNullBitmap);
321 }
322 }
323 }
324}
325
326void wxToolBarSimple::ToggleTool(const int index, const bool toggle)
327{
328 wxNode *node = m_tools.Find((long)index);
329 if (node)
330 {
331 wxToolBarTool *tool = (wxToolBarTool *)node->Data();
332 if (tool && tool->m_isToggle)
333 {
334 bool oldState = tool->m_toggleState;
335 tool->m_toggleState = toggle;
336
337 if (oldState != toggle)
338 {
339 wxMemoryDC memDC;
340 wxClientDC dc(this);
341 DrawTool(dc, memDC, tool);
342 }
343 }
344 }
345}
346
347// Okay, so we've left the tool we're in ... we must check if
348// the tool we're leaving was a 'sprung push button' and if so,
349// spring it back to the up state.
350//
351void wxToolBarSimple::SpringUpButton(const int index)
352{
353 wxNode *node=m_tools.Find((long)index);
354 if (node) {
355 wxToolBarTool *tool = (wxToolBarTool *)node->Data();
356 if (tool && !tool->m_isToggle && tool->m_toggleState){
357 tool->m_toggleState = FALSE;
358 wxMemoryDC memDC;
359 wxClientDC dc(this);
360 DrawTool(dc, memDC, tool);
361 }
362 else if (tool && tool->m_isToggle){
363 tool->m_toggleState = !tool->m_toggleState;
364 wxMemoryDC memDC;
365 wxClientDC dc(this);
366 DrawTool(dc, memDC, tool);
367 }
368 }
369}
370
371#endif