Reverted to my own solution; I think it's better because it distinguishes
[wxWidgets.git] / src / univ / toolbar.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/univ/toolbar.cpp
3 // Author: Robert Roebling
4 // Id: $Id$
5 // Copyright: (c) 2001 Robert Roebling
6 // Licence: wxWindows licence
7 /////////////////////////////////////////////////////////////////////////////
8
9 // ============================================================================
10 // declarations
11 // ============================================================================
12
13 // ----------------------------------------------------------------------------
14 // headers
15 // ----------------------------------------------------------------------------
16
17 #ifdef __GNUG__
18 #pragma implementation "univtoolbar.h"
19 #endif
20
21 // For compilers that support precompilation, includes "wx.h".
22 #include "wx/wxprec.h"
23
24 #ifdef __BORLANDC__
25 #pragma hdrstop
26 #endif
27
28 #ifndef WX_PRECOMP
29 #include "wx/utils.h"
30 #include "wx/app.h"
31 #endif
32
33 #include "wx/toolbar.h"
34 #include "wx/validate.h"
35
36 //-----------------------------------------------------------------------------
37 // wxToolBar
38 //-----------------------------------------------------------------------------
39
40 BEGIN_EVENT_TABLE(wxToolBar,wxToolBarBase)
41 EVT_MOUSE_EVENTS( wxToolBar::OnMouse )
42 EVT_PAINT( wxToolBar::OnPaint )
43 EVT_SIZE( wxToolBar::OnSize )
44 END_EVENT_TABLE()
45
46 bool wxToolBar::Create( wxWindow *parent, wxWindowID id,
47 const wxPoint& pos, const wxSize& size,
48 long style, const wxString& name )
49 {
50 bool ret = wxToolBarBase::Create( parent, id, pos, size, style, wxDefaultValidator, name );
51
52 return ret;
53 }
54
55 void wxToolBar::Init()
56 {
57 // TODO: this is from tbarbase.cpp, but should be in
58 // wxToolbarBase::Init
59 // the list owns the pointers
60 m_tools.DeleteContents(TRUE);
61 m_xMargin = m_yMargin = 0;
62 m_maxRows = m_maxCols = 0;
63 // End TODO
64
65 m_maxWidth = 0;
66 m_maxHeight = 0;
67
68 m_captured = NULL;
69 SetToolBitmapSize( wxSize(16,15) );
70 }
71
72 wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord x, wxCoord y) const
73 {
74 return NULL;
75 }
76
77 void wxToolBar::SetToolShortHelp(int id, const wxString& helpString)
78 {
79 }
80
81 bool wxToolBar::DoInsertTool(size_t pos, wxToolBarToolBase *tool)
82 {
83 return TRUE;
84 }
85
86 bool wxToolBar::DoDeleteTool(size_t pos, wxToolBarToolBase *tool)
87 {
88 return TRUE;
89 }
90
91 void wxToolBar::DoEnableTool(wxToolBarToolBase *tool, bool enable)
92 {
93 }
94
95 void wxToolBar::DoToggleTool(wxToolBarToolBase *tool, bool toggle)
96 {
97 wxToolBarTool *my_tool = (wxToolBarTool*) tool;
98
99 bool refresh = (my_tool->IsToggled() != toggle);
100
101 my_tool->m_isDown = toggle;
102
103 if (refresh)
104 RefreshTool( my_tool );
105 }
106
107 void wxToolBar::DoSetToggle(wxToolBarToolBase *tool, bool toggle)
108 {
109 }
110
111 wxToolBarToolBase *wxToolBar::CreateTool(int id,
112 const wxBitmap& bitmap1,
113 const wxBitmap& bitmap2,
114 bool toggle,
115 wxObject *clientData,
116 const wxString& shortHelpString,
117 const wxString& longHelpString)
118 {
119 return new wxToolBarTool( this, id, bitmap1, bitmap2, toggle,
120 clientData, shortHelpString, longHelpString);
121 }
122
123 wxToolBarToolBase *wxToolBar::CreateTool(wxControl *control)
124 {
125 wxFAIL_MSG( wxT("Toolbar doesn't support controls yet.") );
126
127 return NULL;
128 }
129
130 void wxToolBar::RefreshTool( wxToolBarTool *tool )
131 {
132 wxRect rect( tool->m_x, tool->m_y, m_defaultWidth+6, m_defaultHeight+6 );
133 Refresh( TRUE, &rect );
134 }
135
136 void wxToolBar::DrawToolBarTool( wxToolBarTool *tool, wxDC &dc, bool down )
137 {
138 if (down)
139 {
140 dc.DrawBitmap( tool->GetBitmap1(), tool->m_x+4, tool->m_y+4, TRUE );
141
142 dc.SetPen( *wxGREY_PEN );
143 dc.DrawLine( tool->m_x, tool->m_y, tool->m_x+m_defaultWidth+5, tool->m_y );
144 dc.DrawLine( tool->m_x, tool->m_y, tool->m_x, tool->m_y+m_defaultHeight+5 );
145
146 dc.SetPen( *wxBLACK_PEN );
147 dc.DrawLine( tool->m_x+1, tool->m_y+1, tool->m_x+m_defaultWidth+4, tool->m_y+1 );
148 dc.DrawLine( tool->m_x+1, tool->m_y+1, tool->m_x+1, tool->m_y+m_defaultHeight+4 );
149
150 dc.SetPen( *wxWHITE_PEN );
151 dc.DrawLine( tool->m_x, tool->m_y+m_defaultHeight+5, tool->m_x+m_defaultWidth+6, tool->m_y+m_defaultHeight+5 );
152 dc.DrawLine( tool->m_x+m_defaultWidth+5, tool->m_y, tool->m_x+m_defaultWidth+5, tool->m_y+m_defaultHeight+6 );
153 }
154 else
155 {
156 dc.DrawBitmap( tool->GetBitmap1(), tool->m_x+3, tool->m_y+3, TRUE );
157
158 dc.SetPen( *wxWHITE_PEN );
159 dc.DrawLine( tool->m_x, tool->m_y, tool->m_x+m_defaultWidth+5, tool->m_y );
160 dc.DrawLine( tool->m_x, tool->m_y, tool->m_x, tool->m_y+m_defaultHeight+5 );
161 dc.DrawLine( tool->m_x+m_defaultWidth+4, tool->m_y, tool->m_x+m_defaultWidth+4, tool->m_y+2 );
162 dc.DrawLine( tool->m_x, tool->m_y+m_defaultHeight+4, tool->m_x+2, tool->m_y+m_defaultHeight+4 );
163
164 dc.SetPen( *wxBLACK_PEN );
165 dc.DrawLine( tool->m_x, tool->m_y+m_defaultHeight+5, tool->m_x+m_defaultWidth+6, tool->m_y+m_defaultHeight+5 );
166 dc.DrawLine( tool->m_x+m_defaultWidth+5, tool->m_y, tool->m_x+m_defaultWidth+5, tool->m_y+m_defaultHeight+6 );
167
168 dc.SetPen( *wxGREY_PEN );
169 dc.DrawLine( tool->m_x+1, tool->m_y+m_defaultHeight+4, tool->m_x+m_defaultWidth+5, tool->m_y+m_defaultHeight+4 );
170 dc.DrawLine( tool->m_x+m_defaultWidth+4, tool->m_y+1, tool->m_x+m_defaultWidth+4, tool->m_y+m_defaultHeight+5 );
171 }
172 }
173
174 void wxToolBar::OnPaint(wxPaintEvent &event)
175 {
176 wxPaintDC dc(this);
177
178 wxSize clientSize = GetClientSize();
179 dc.SetPen( *wxBLACK_PEN );
180 dc.DrawLine( 0,0, clientSize.x,0 );
181
182 for ( wxToolBarToolsList::Node *node = m_tools.GetFirst();
183 node;
184 node = node->GetNext() )
185 {
186 wxToolBarTool *tool = (wxToolBarTool*) node->Data();
187
188 if (tool->GetId() == -1) continue;
189
190 DrawToolBarTool( tool, dc, tool->m_isDown );
191 }
192 }
193
194 bool wxToolBar::Realize()
195 {
196 if (!wxToolBarBase::Realize())
197 return FALSE;
198
199 int x;
200 int y;
201
202 if (GetWindowStyleFlag() & wxTB_VERTICAL)
203 {
204 x = m_xMargin;
205 y = 5;
206 }
207 else
208 {
209 y = m_yMargin;
210 x = 5;
211 }
212
213 for ( wxToolBarToolsList::Node *node = m_tools.GetFirst();
214 node;
215 node = node->GetNext() )
216 {
217 wxToolBarTool *tool = (wxToolBarTool*) node->Data();
218
219 if (GetWindowStyleFlag() & wxTB_VERTICAL)
220 {
221 if (tool->GetId() == -1)
222 {
223 y += 6;
224 continue;
225 }
226 tool->m_x = m_xMargin;
227 tool->m_y = y;
228 y += m_defaultHeight + 6;
229
230 // Calculate the maximum height or width (depending on style)
231 // so we know how to size the toolbar in Realize.
232 // We could get the size of the tool instead of the
233 // default bitmap size
234 if (m_maxWidth < (m_defaultWidth + 2*(m_xMargin + 2)))
235 m_maxWidth = (m_defaultWidth + 2*(m_xMargin + 2)) ;
236 }
237 else
238 {
239 if (tool->GetId() == -1)
240 {
241 x += 6;
242 continue;
243 }
244 tool->m_x = x;
245 tool->m_y = m_yMargin;
246 x += m_defaultWidth + 6;
247
248 // Calculate the maximum height or width (depending on style)
249 // so we know how to size the toolbar in Realize.
250 // We could get the size of the tool instead of the
251 // default bitmap size
252 if (m_maxHeight < (m_defaultHeight + 2*(m_yMargin + 2)))
253 m_maxHeight = (m_defaultHeight + 2*(m_yMargin + 2)) ;
254 }
255
256 }
257
258 wxSize sz = GetSize();
259 if (GetWindowStyleFlag() & wxTB_VERTICAL)
260 {
261 SetSize(m_maxWidth, sz.y);
262 }
263 else
264 {
265 SetSize(sz.x, m_maxHeight);
266 }
267
268 // Commenting out Robert's fix since the above should be
269 // more general
270 // SetSize( x+16, m_defaultHeight + 14 );
271
272 return TRUE;
273 }
274
275 void wxToolBar::OnMouse(wxMouseEvent &event)
276 {
277 wxToolBarTool *hit = NULL;
278 int x = event.GetX();
279 int y = event.GetY();
280
281 for ( wxToolBarToolsList::Node *node = m_tools.GetFirst();
282 node;
283 node = node->GetNext() )
284 {
285 wxToolBarTool *tool = (wxToolBarTool*) node->Data();
286
287 if ((x > tool->m_x) && (x < tool->m_x+m_defaultWidth+5) &&
288 (y > tool->m_y) && (y < tool->m_y+m_defaultHeight+5))
289 {
290 hit = tool;
291 break;
292 }
293 }
294
295 if (event.LeftDown() && (hit))
296 {
297 CaptureMouse();
298 m_captured = hit;
299
300 m_captured->m_isDown = TRUE;
301 RefreshTool( m_captured );
302
303 return;
304 }
305
306 if (event.Dragging() && (m_captured))
307 {
308 bool is_down = (hit == m_captured);
309 if (is_down != m_captured->m_isDown)
310 {
311 m_captured->m_isDown = is_down;
312 RefreshTool( m_captured );
313 }
314
315 return;
316 }
317
318 if (event.LeftUp() && (m_captured))
319 {
320 ReleaseMouse();
321
322 m_captured->m_isDown = FALSE;
323 RefreshTool( m_captured );
324
325 if (hit == m_captured)
326 {
327 wxCommandEvent cevent( wxEVT_COMMAND_TOOL_CLICKED, m_captured->GetId() );
328 cevent.SetEventObject( this );
329 // cevent.SetExtraLong((long) toggleDown);
330 GetEventHandler()->ProcessEvent( cevent );
331 }
332
333 m_captured = NULL;
334
335 return;
336 }
337 }
338