]>
Commit | Line | Data |
---|---|---|
2bda0e17 KB |
1 | ///////////////////////////////////////////////////////////////////////////// |
2 | // Name: tbarmsw.cpp | |
8a0681f9 | 3 | // Purpose: wxToolBar |
2bda0e17 | 4 | // Author: Julian Smart |
8a0681f9 | 5 | // Modified by: 13.12.99 by VZ during toolbar classes reorganization |
2bda0e17 KB |
6 | // Created: 04/01/98 |
7 | // RCS-ID: $Id$ | |
6c9a19aa JS |
8 | // Copyright: (c) Julian Smart |
9 | // Licence: wxWindows licence | |
2bda0e17 KB |
10 | ///////////////////////////////////////////////////////////////////////////// |
11 | ||
8a0681f9 VZ |
12 | // ============================================================================ |
13 | // declarations | |
14 | // ============================================================================ | |
15 | ||
16 | // ---------------------------------------------------------------------------- | |
17 | // headers | |
18 | // ---------------------------------------------------------------------------- | |
19 | ||
14f355c2 | 20 | #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) |
8a0681f9 | 21 | #pragma implementation "tbarmsw.h" |
2bda0e17 KB |
22 | #endif |
23 | ||
24 | // For compilers that support precompilation, includes "wx.h". | |
25 | #include "wx/wxprec.h" | |
26 | ||
27 | #ifdef __BORLANDC__ | |
8a0681f9 | 28 | #pragma hdrstop |
2bda0e17 KB |
29 | #endif |
30 | ||
31 | #ifndef WX_PRECOMP | |
8a0681f9 | 32 | #include "wx/wx.h" |
2bda0e17 KB |
33 | #endif |
34 | ||
c25a510b | 35 | #if wxUSE_TOOLBAR && defined(__WIN16__) |
8a0681f9 | 36 | |
ce3ed50d | 37 | #if !defined(__GNUWIN32__) && !defined(__SALFORDC__) |
8a0681f9 | 38 | #include "malloc.h" |
2bda0e17 KB |
39 | #endif |
40 | ||
ce3ed50d | 41 | #if !defined(__MWERKS__) && !defined(__SALFORDC__) |
8a0681f9 | 42 | #include <memory.h> |
17dff81c | 43 | #endif |
ce3ed50d | 44 | |
2bda0e17 KB |
45 | #include <stdlib.h> |
46 | ||
c25a510b | 47 | #include "wx/msw/tbarmsw.h" |
2432b92d | 48 | #include "wx/event.h" |
2bda0e17 | 49 | #include "wx/app.h" |
2432b92d | 50 | #include "wx/bitmap.h" |
2bda0e17 KB |
51 | #include "wx/msw/private.h" |
52 | #include "wx/msw/dib.h" | |
53 | ||
8a0681f9 VZ |
54 | // ---------------------------------------------------------------------------- |
55 | // constants | |
56 | // ---------------------------------------------------------------------------- | |
57 | ||
81d66cf3 JS |
58 | #define DEFAULTBITMAPX 16 |
59 | #define DEFAULTBITMAPY 15 | |
60 | #define DEFAULTBUTTONX 24 | |
61 | #define DEFAULTBUTTONY 22 | |
62 | #define DEFAULTBARHEIGHT 27 | |
63 | ||
8a0681f9 VZ |
64 | // |
65 | // States (not all of them currently used) | |
66 | // | |
67 | #define wxTBSTATE_CHECKED 0x01 // radio button is checked | |
68 | #define wxTBSTATE_PRESSED 0x02 // button is being depressed (any style) | |
69 | #define wxTBSTATE_ENABLED 0x04 // button is enabled | |
70 | #define wxTBSTATE_HIDDEN 0x08 // button is hidden | |
71 | #define wxTBSTATE_INDETERMINATE 0x10 // button is indeterminate | |
2bda0e17 | 72 | |
8a0681f9 VZ |
73 | // ---------------------------------------------------------------------------- |
74 | // private classes | |
75 | // ---------------------------------------------------------------------------- | |
2bda0e17 | 76 | |
8a0681f9 VZ |
77 | class WXDLLEXPORT wxToolBarTool : public wxToolBarToolBase |
78 | { | |
79 | public: | |
80 | wxToolBarTool(wxToolBar *tbar, | |
81 | int id, | |
a3399e6c VZ |
82 | const wxBitmap& bmpNormal, |
83 | const wxBitmap& bmpDisabled, | |
8a0681f9 VZ |
84 | bool toggle, |
85 | wxObject *clientData, | |
a3399e6c VZ |
86 | const wxString& shortHelp, |
87 | const wxString& longHelp) | |
88 | : wxToolBarToolBase(tbar, id, bmpNormal, bmpDisabled, toggle, | |
89 | clientData, shortHelp, longHelp) | |
8a0681f9 VZ |
90 | { |
91 | } | |
92 | ||
93 | wxToolBarTool(wxToolBar *tbar, wxControl *control) | |
94 | : wxToolBarToolBase(tbar, control) | |
95 | { | |
96 | } | |
2bda0e17 | 97 | |
8a0681f9 VZ |
98 | void SetSize(const wxSize& size) |
99 | { | |
100 | m_width = size.x; | |
101 | m_height = size.y; | |
102 | } | |
103 | ||
104 | long GetWidth() const { return m_width; } | |
105 | long GetHeight() const { return m_height; } | |
106 | ||
107 | wxCoord m_x; | |
108 | wxCoord m_y; | |
109 | wxCoord m_width; | |
110 | wxCoord m_height; | |
111 | }; | |
112 | ||
113 | // ---------------------------------------------------------------------------- | |
114 | // wxWin macros | |
115 | // ---------------------------------------------------------------------------- | |
116 | ||
117 | #if !USE_SHARED_LIBRARY | |
12ed316d | 118 | IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxToolBarBase) |
8a0681f9 VZ |
119 | |
120 | BEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase) | |
121 | EVT_PAINT(wxToolBar::OnPaint) | |
122 | EVT_MOUSE_EVENTS(wxToolBar::OnMouseEvent) | |
2bda0e17 | 123 | END_EVENT_TABLE() |
8a0681f9 VZ |
124 | #endif |
125 | ||
126 | // ============================================================================ | |
127 | // implementation | |
128 | // ============================================================================ | |
129 | ||
130 | // ---------------------------------------------------------------------------- | |
131 | // wxToolBarTool | |
132 | // ---------------------------------------------------------------------------- | |
133 | ||
134 | wxToolBarToolBase *wxToolBar::CreateTool(int id, | |
a3399e6c VZ |
135 | const wxString& label, |
136 | const wxBitmap& bmpNormal, | |
137 | const wxBitmap& bmpDisabled, | |
138 | wxItemKind kind, | |
8a0681f9 | 139 | wxObject *clientData, |
a3399e6c VZ |
140 | const wxString& shortHelp, |
141 | const wxString& longHelp) | |
8a0681f9 | 142 | { |
a3399e6c VZ |
143 | return new wxToolBarTool(this, id, label, bmpNormal, bmpDisabled, kind, |
144 | clientData, shortHelp, longHelp); | |
8a0681f9 | 145 | } |
2bda0e17 | 146 | |
8a0681f9 | 147 | wxToolBarToolBase *wxToolBar::CreateTool(wxControl *control) |
2bda0e17 | 148 | { |
8a0681f9 | 149 | return new wxToolBarTool(this, control); |
2bda0e17 KB |
150 | } |
151 | ||
8a0681f9 VZ |
152 | // ---------------------------------------------------------------------------- |
153 | // wxToolBar | |
154 | // ---------------------------------------------------------------------------- | |
155 | ||
156 | void wxToolBar::Init() | |
2bda0e17 | 157 | { |
8a0681f9 VZ |
158 | m_hbrDither = 0; |
159 | m_rgbFace = 0; | |
160 | m_rgbShadow = 0; | |
161 | m_rgbHilight = 0; | |
162 | m_rgbFrame = 0; | |
163 | m_hdcMono = 0; | |
164 | m_hbmMono = 0; | |
165 | m_hbmDefault = 0; | |
166 | ||
167 | m_defaultWidth = DEFAULTBITMAPX; | |
168 | m_defaultHeight = DEFAULTBITMAPY; | |
2bda0e17 | 169 | |
8a0681f9 VZ |
170 | m_xPos = |
171 | m_yPos = -1; | |
2bda0e17 | 172 | |
8a0681f9 VZ |
173 | m_maxWidth = m_maxHeight = 0; |
174 | m_pressedTool = m_currentTool = -1; | |
175 | m_toolPacking = 1; | |
176 | m_toolSeparation = 5; | |
177 | } | |
2bda0e17 | 178 | |
8a0681f9 VZ |
179 | bool wxToolBar::Create(wxWindow *parent, |
180 | wxWindowID id, | |
181 | const wxPoint& pos, | |
182 | const wxSize& size, | |
183 | long style, | |
184 | const wxString& name) | |
185 | { | |
186 | if ( !wxWindow::Create(parent, id, pos, size, style, name) ) | |
187 | return FALSE; | |
2bda0e17 | 188 | |
8a0681f9 VZ |
189 | if ( style & wxTB_HORIZONTAL ) |
190 | { | |
191 | m_lastX = 3; | |
192 | m_lastY = 7; | |
193 | } | |
194 | else | |
195 | { | |
196 | m_lastX = 7; | |
197 | m_lastY = 3; | |
198 | } | |
2bda0e17 | 199 | |
8a0681f9 VZ |
200 | // Set it to grey |
201 | SetBackgroundColour(wxColour(192, 192, 192)); | |
202 | ||
203 | InitGlobalObjects(); | |
204 | ||
205 | return TRUE; | |
2bda0e17 KB |
206 | } |
207 | ||
8a0681f9 | 208 | wxToolBar::~wxToolBar() |
2bda0e17 | 209 | { |
8a0681f9 | 210 | FreeGlobalObjects(); |
2bda0e17 KB |
211 | } |
212 | ||
8a0681f9 | 213 | void wxToolBar::SetToolBitmapSize(const wxSize& size) |
2bda0e17 | 214 | { |
8a0681f9 VZ |
215 | m_defaultWidth = size.x; |
216 | m_defaultHeight = size.y; | |
217 | ||
218 | FreeGlobalObjects(); | |
219 | InitGlobalObjects(); | |
2bda0e17 KB |
220 | } |
221 | ||
222 | // The button size is bigger than the bitmap size | |
8a0681f9 | 223 | wxSize wxToolBar::GetToolSize() const |
2bda0e17 | 224 | { |
8a0681f9 | 225 | return wxSize(m_defaultWidth + 8, m_defaultHeight + 7); |
2bda0e17 KB |
226 | } |
227 | ||
8a0681f9 | 228 | wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord x, wxCoord y) const |
2bda0e17 | 229 | { |
8a0681f9 VZ |
230 | wxToolBarToolsList::Node *node = m_tools.GetFirst(); |
231 | while (node) | |
232 | { | |
233 | wxToolBarTool *tool = (wxToolBarTool *)node->GetData(); | |
234 | if ((x >= tool->m_x) && (y >= tool->m_y) && | |
235 | (x <= (tool->m_x + tool->GetWidth())) && | |
236 | (y <= (tool->m_y + tool->GetHeight()))) | |
237 | { | |
238 | return tool; | |
239 | } | |
2bda0e17 | 240 | |
8a0681f9 VZ |
241 | node = node->GetNext(); |
242 | } | |
2bda0e17 | 243 | |
8a0681f9 VZ |
244 | return (wxToolBarToolBase *)NULL; |
245 | } | |
2bda0e17 | 246 | |
8a0681f9 VZ |
247 | wxToolBarToolBase *wxToolBar::AddTool(int id, |
248 | const wxBitmap& bitmap, | |
249 | const wxBitmap& pushedBitmap, | |
250 | bool toggle, | |
251 | wxCoord xPos, | |
252 | wxCoord yPos, | |
253 | wxObject *clientData, | |
254 | const wxString& helpString1, | |
255 | const wxString& helpString2) | |
256 | { | |
257 | // rememeber the position for DoInsertTool() | |
258 | m_xPos = xPos; | |
259 | m_yPos = yPos; | |
260 | ||
261 | return wxToolBarBase::AddTool(id, bitmap, pushedBitmap, toggle, | |
262 | xPos, yPos, clientData, | |
263 | helpString1, helpString2); | |
2bda0e17 KB |
264 | } |
265 | ||
8a0681f9 | 266 | void wxToolBar::OnPaint(wxPaintEvent& event) |
2bda0e17 | 267 | { |
8a0681f9 VZ |
268 | wxPaintDC dc(this); |
269 | ||
270 | static int wxOnPaintCount = 0; | |
271 | ||
272 | // Prevent reentry of OnPaint which would cause | |
273 | // wxMemoryDC errors. | |
274 | if (wxOnPaintCount > 0) | |
275 | return; | |
276 | wxOnPaintCount++; | |
277 | ||
278 | wxToolBarToolsList::Node *node = m_tools.GetFirst(); | |
279 | while (node) | |
280 | { | |
281 | wxToolBarToolBase *tool = node->GetData(); | |
282 | if ( tool->GetStyle()!= wxTOOL_STYLE_BUTTON ) | |
283 | { | |
284 | int state = tool->IsEnabled() ? wxTBSTATE_ENABLED : 0; | |
285 | if ( tool->IsToggled() ) | |
286 | state |= wxTBSTATE_CHECKED; | |
287 | ||
288 | DrawTool(dc, tool, state); | |
289 | } | |
290 | ||
291 | node = node->GetNext(); | |
292 | } | |
293 | ||
294 | wxOnPaintCount--; | |
2bda0e17 KB |
295 | } |
296 | ||
297 | // If a Button is disabled, then NO function (besides leaving | |
298 | // or entering) should be carried out. Therefore the additions | |
299 | // of 'enabled' testing (Stefan Hammes). | |
8a0681f9 | 300 | void wxToolBar::OnMouseEvent(wxMouseEvent& event) |
2bda0e17 | 301 | { |
8a0681f9 VZ |
302 | static wxToolBarToolBase *eventCurrentTool = NULL; |
303 | wxClientDC dc(this); | |
2bda0e17 | 304 | |
8a0681f9 | 305 | if (event.Leaving()) |
2bda0e17 | 306 | { |
8a0681f9 VZ |
307 | m_currentTool = -1; |
308 | if (eventCurrentTool && eventCurrentTool->IsEnabled()) | |
309 | { | |
310 | ::ReleaseCapture(); | |
311 | int state = wxTBSTATE_ENABLED; | |
312 | if (eventCurrentTool->IsToggled()) | |
313 | state |= wxTBSTATE_CHECKED; | |
314 | DrawTool(dc, eventCurrentTool, state); | |
315 | eventCurrentTool = NULL; | |
316 | } | |
317 | OnMouseEnter(-1); | |
318 | return; | |
2bda0e17 | 319 | } |
2bda0e17 | 320 | |
8a0681f9 VZ |
321 | wxCoord x, y; |
322 | event.GetPosition(&x, &y); | |
323 | wxToolBarToolBase *tool = FindToolForPosition(x, y); | |
2bda0e17 | 324 | |
8a0681f9 | 325 | if (!tool) |
2bda0e17 | 326 | { |
8a0681f9 VZ |
327 | if (eventCurrentTool && eventCurrentTool->IsEnabled()) |
328 | { | |
329 | ::ReleaseCapture(); | |
330 | ||
331 | int state = wxTBSTATE_ENABLED; | |
332 | if (eventCurrentTool->IsToggled()) | |
333 | state |= wxTBSTATE_CHECKED; | |
334 | DrawTool(dc, eventCurrentTool, state); | |
335 | eventCurrentTool = NULL; | |
336 | } | |
337 | if (m_currentTool > -1) | |
338 | { | |
339 | m_currentTool = -1; | |
340 | OnMouseEnter(-1); | |
341 | } | |
342 | return; | |
2bda0e17 | 343 | } |
8a0681f9 VZ |
344 | |
345 | if (!event.Dragging() && !event.IsButton()) | |
2bda0e17 | 346 | { |
8a0681f9 VZ |
347 | if (tool->GetId() != m_currentTool) |
348 | { | |
349 | OnMouseEnter(m_currentTool = tool->GetId()); | |
350 | return; | |
351 | } | |
2bda0e17 | 352 | } |
8a0681f9 | 353 | if (event.Dragging() && tool->IsEnabled()) |
2bda0e17 | 354 | { |
8a0681f9 VZ |
355 | if (eventCurrentTool) |
356 | { | |
357 | // Might have dragged outside tool | |
358 | if (eventCurrentTool != tool) | |
359 | { | |
360 | int state = wxTBSTATE_ENABLED; | |
361 | if (tool->IsToggled()) | |
362 | state |= wxTBSTATE_CHECKED; | |
363 | DrawTool(dc, tool, state); | |
364 | eventCurrentTool = NULL; | |
365 | return; | |
366 | } | |
367 | } | |
368 | else | |
369 | { | |
370 | if (tool && event.LeftIsDown() && tool->IsEnabled()) | |
371 | { | |
372 | eventCurrentTool = tool; | |
373 | ::SetCapture((HWND) GetHWND()); | |
374 | int state = wxTBSTATE_ENABLED|wxTBSTATE_PRESSED; | |
375 | if (tool->IsToggled()) | |
376 | state |= wxTBSTATE_CHECKED; | |
377 | DrawTool(dc, tool, state); | |
378 | } | |
379 | } | |
2bda0e17 | 380 | } |
8a0681f9 | 381 | if (event.LeftDown() && tool->IsEnabled()) |
2bda0e17 | 382 | { |
2bda0e17 KB |
383 | eventCurrentTool = tool; |
384 | ::SetCapture((HWND) GetHWND()); | |
385 | int state = wxTBSTATE_ENABLED|wxTBSTATE_PRESSED; | |
8a0681f9 VZ |
386 | if (tool->IsToggled()) |
387 | state |= wxTBSTATE_CHECKED; | |
2bda0e17 | 388 | DrawTool(dc, tool, state); |
2bda0e17 | 389 | } |
8a0681f9 | 390 | else if (event.LeftUp() && tool->IsEnabled()) |
2bda0e17 | 391 | { |
8a0681f9 VZ |
392 | if (eventCurrentTool) |
393 | ::ReleaseCapture(); | |
394 | if (eventCurrentTool == tool) | |
2bda0e17 | 395 | { |
8a0681f9 VZ |
396 | if (tool->CanBeToggled()) |
397 | { | |
398 | tool->Toggle(); | |
399 | if (!OnLeftClick(tool->GetId(), tool->IsToggled())) | |
400 | { | |
401 | tool->Toggle(); | |
402 | } | |
403 | int state = wxTBSTATE_ENABLED; | |
404 | if (tool->IsToggled()) | |
405 | state |= wxTBSTATE_CHECKED; | |
406 | DrawTool(dc, tool, state); | |
407 | } | |
408 | else | |
409 | { | |
410 | int state = wxTBSTATE_ENABLED; | |
411 | if (tool->IsToggled()) | |
412 | state |= wxTBSTATE_CHECKED; | |
413 | DrawTool(dc, tool, state); | |
414 | OnLeftClick(tool->GetId(), tool->IsToggled()); | |
415 | } | |
2bda0e17 | 416 | } |
8a0681f9 VZ |
417 | eventCurrentTool = NULL; |
418 | } | |
419 | else if (event.RightDown() && tool->IsEnabled()) | |
420 | { | |
421 | OnRightClick(tool->GetId(), x, y); | |
2bda0e17 | 422 | } |
2bda0e17 KB |
423 | } |
424 | ||
8a0681f9 | 425 | void wxToolBar::DoEnableTool(wxToolBarToolBase *tool, bool WXUNUSED(enable)) |
2bda0e17 | 426 | { |
8a0681f9 | 427 | DoRedrawTool(tool); |
2bda0e17 KB |
428 | } |
429 | ||
8a0681f9 | 430 | void wxToolBar::DoToggleTool(wxToolBarToolBase *tool, bool WXUNUSED(toggle)) |
2bda0e17 | 431 | { |
8a0681f9 | 432 | DoRedrawTool(tool); |
2bda0e17 KB |
433 | } |
434 | ||
8a0681f9 VZ |
435 | void wxToolBar::DoSetToggle(wxToolBarToolBase * WXUNUSED(tool), |
436 | bool WXUNUSED(toggle)) | |
2bda0e17 | 437 | { |
8a0681f9 | 438 | // nothing to do |
2bda0e17 KB |
439 | } |
440 | ||
8a0681f9 | 441 | void wxToolBar::DoRedrawTool(wxToolBarToolBase *tool) |
2bda0e17 | 442 | { |
8a0681f9 | 443 | wxClientDC dc(this); |
2bda0e17 | 444 | |
8a0681f9 VZ |
445 | DrawTool(dc, tool); |
446 | } | |
2bda0e17 | 447 | |
8a0681f9 VZ |
448 | void wxToolBar::DrawTool(wxDC& dc, wxToolBarToolBase *toolBase, int state) |
449 | { | |
450 | wxToolBarTool *tool = (wxToolBarTool *)toolBase; | |
2bda0e17 | 451 | |
8a0681f9 VZ |
452 | DrawButton(dc.GetHDC(), |
453 | tool->m_x, tool->m_y, | |
454 | tool->GetWidth(), tool->GetHeight(), | |
455 | tool, state); | |
456 | } | |
2bda0e17 | 457 | |
8a0681f9 VZ |
458 | void wxToolBar::DrawTool(wxDC& dc, wxToolBarToolBase *tool) |
459 | { | |
460 | int state = 0; | |
461 | if (tool->IsEnabled()) | |
462 | state |= wxTBSTATE_ENABLED; | |
463 | if (tool->IsToggled()) | |
464 | state |= wxTBSTATE_CHECKED; | |
465 | // how can i access the PRESSED state??? | |
2bda0e17 | 466 | |
8a0681f9 VZ |
467 | DrawTool(dc, tool, state); |
468 | } | |
2bda0e17 | 469 | |
8a0681f9 VZ |
470 | bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos), |
471 | wxToolBarToolBase *tool) | |
472 | { | |
473 | // VZ: didn't test whether it works, but why not... | |
474 | tool->Detach(); | |
2bda0e17 | 475 | |
8a0681f9 | 476 | Refresh(); |
2bda0e17 | 477 | |
8a0681f9 | 478 | return TRUE; |
2bda0e17 KB |
479 | } |
480 | ||
8a0681f9 | 481 | bool wxToolBar::DoInsertTool(size_t pos, wxToolBarToolBase *toolBase) |
81d66cf3 | 482 | { |
8a0681f9 | 483 | wxToolBarTool *tool = (wxToolBarTool *)toolBase; |
81d66cf3 | 484 | |
8a0681f9 VZ |
485 | wxCHECK_MSG( !tool->IsControl(), FALSE, |
486 | _T("generic wxToolBar doesn't support controls") ); | |
487 | ||
488 | // TODO: use the mapping code from wxToolBar95 to get it right in this class | |
489 | #if !defined(__WIN32__) && !defined(__WIN386__) | |
a3399e6c | 490 | wxBitmap bmpDisabled; |
c25a510b | 491 | if (tool->CanBeToggled()) |
8a0681f9 VZ |
492 | { |
493 | HBITMAP hbmp = CreateMappedBitmap((WXHINSTANCE)wxGetInstance(), | |
494 | GetHbitmapOf(tool->GetBitmap1())); | |
495 | ||
496 | wxBitmap bmp; | |
497 | bmp.SetHBITMAP((WXHBITMAP)hbmp); | |
498 | tool->SetBitmap2(bmp); | |
499 | } | |
500 | #endif | |
81d66cf3 | 501 | |
8a0681f9 VZ |
502 | tool->m_x = m_xPos; |
503 | if ( tool->m_x == -1 ) | |
504 | tool->m_x = m_xMargin; | |
81d66cf3 | 505 | |
8a0681f9 VZ |
506 | tool->m_y = m_yPos; |
507 | if ( tool->m_y == -1 ) | |
508 | tool->m_y = m_yMargin; | |
509 | ||
510 | tool->SetSize(GetToolSize()); | |
511 | ||
512 | if ( tool->IsButton() ) | |
81d66cf3 | 513 | { |
8a0681f9 VZ |
514 | // Calculate reasonable max size in case Layout() not called |
515 | if ((tool->m_x + tool->GetBitmap1().GetWidth() + m_xMargin) > m_maxWidth) | |
516 | m_maxWidth = (tool->m_x + tool->GetWidth() + m_xMargin); | |
517 | ||
518 | if ((tool->m_y + tool->GetBitmap1().GetHeight() + m_yMargin) > m_maxHeight) | |
519 | m_maxHeight = (tool->m_y + tool->GetHeight() + m_yMargin); | |
81d66cf3 | 520 | } |
8a0681f9 VZ |
521 | |
522 | return TRUE; | |
523 | } | |
524 | ||
525 | bool wxToolBar::Realize() | |
526 | { | |
527 | m_currentRowsOrColumns = 0; | |
528 | m_lastX = m_xMargin; | |
529 | m_lastY = m_yMargin; | |
530 | int maxToolWidth = 0; | |
531 | int maxToolHeight = 0; | |
532 | m_maxWidth = 0; | |
533 | m_maxHeight = 0; | |
534 | ||
535 | // Find the maximum tool width and height | |
536 | wxToolBarToolsList::Node *node = m_tools.GetFirst(); | |
537 | while (node) | |
81d66cf3 | 538 | { |
8a0681f9 VZ |
539 | wxToolBarTool *tool = (wxToolBarTool *)node->GetData(); |
540 | if (tool->GetWidth() > maxToolWidth) | |
541 | maxToolWidth = tool->GetWidth(); | |
542 | if (tool->GetHeight() > maxToolHeight) | |
543 | maxToolHeight = tool->GetHeight(); | |
544 | node = node->GetNext(); | |
545 | } | |
546 | ||
547 | int separatorSize = m_toolSeparation; | |
548 | ||
549 | node = m_tools.GetFirst(); | |
550 | while (node) | |
551 | { | |
552 | wxToolBarTool *tool = (wxToolBarTool *)node->GetData(); | |
553 | if (tool->GetStyle() == wxTOOL_STYLE_SEPARATOR) | |
81d66cf3 | 554 | { |
8a0681f9 VZ |
555 | if ( GetWindowStyleFlag() & wxTB_HORIZONTAL ) |
556 | { | |
557 | if (m_currentRowsOrColumns >= m_maxCols) | |
558 | m_lastY += separatorSize; | |
559 | else | |
560 | m_lastX += separatorSize; | |
561 | } | |
562 | else | |
563 | { | |
564 | if (m_currentRowsOrColumns >= m_maxRows) | |
565 | m_lastX += separatorSize; | |
566 | else | |
567 | m_lastY += separatorSize; | |
568 | } | |
81d66cf3 | 569 | } |
8a0681f9 | 570 | else if (tool->GetStyle() == wxTOOL_STYLE_BUTTON) |
81d66cf3 | 571 | { |
8a0681f9 VZ |
572 | if ( GetWindowStyleFlag() & wxTB_HORIZONTAL ) |
573 | { | |
574 | if (m_currentRowsOrColumns >= m_maxCols) | |
575 | { | |
576 | m_currentRowsOrColumns = 0; | |
577 | m_lastX = m_xMargin; | |
578 | m_lastY += maxToolHeight + m_toolPacking; | |
579 | } | |
580 | tool->m_x = (long) (m_lastX + (maxToolWidth - tool->GetWidth())/2.0); | |
581 | tool->m_y = (long) (m_lastY + (maxToolHeight - tool->GetHeight())/2.0); | |
582 | ||
583 | m_lastX += maxToolWidth + m_toolPacking; | |
584 | } | |
585 | else | |
586 | { | |
587 | if (m_currentRowsOrColumns >= m_maxRows) | |
588 | { | |
589 | m_currentRowsOrColumns = 0; | |
590 | m_lastX += (maxToolWidth + m_toolPacking); | |
591 | m_lastY = m_yMargin; | |
592 | } | |
593 | tool->m_x = (long) (m_lastX + (maxToolWidth - tool->GetWidth())/2.0); | |
594 | tool->m_y = (long) (m_lastY + (maxToolHeight - tool->GetHeight())/2.0); | |
595 | ||
596 | m_lastY += maxToolHeight + m_toolPacking; | |
597 | } | |
598 | m_currentRowsOrColumns ++; | |
81d66cf3 | 599 | } |
8a0681f9 VZ |
600 | |
601 | if (m_lastX > m_maxWidth) | |
602 | m_maxWidth = m_lastX; | |
603 | if (m_lastY > m_maxHeight) | |
604 | m_maxHeight = m_lastY; | |
605 | ||
606 | node = node->GetNext(); | |
81d66cf3 | 607 | } |
81d66cf3 | 608 | |
8a0681f9 VZ |
609 | if ( GetWindowStyleFlag() & wxTB_HORIZONTAL ) |
610 | { | |
611 | m_maxWidth += maxToolWidth; | |
612 | m_maxHeight += maxToolHeight; | |
613 | } | |
614 | else | |
615 | { | |
616 | m_maxWidth += maxToolWidth; | |
617 | m_maxHeight += maxToolHeight; | |
618 | } | |
81d66cf3 | 619 | |
8a0681f9 VZ |
620 | m_maxWidth += m_xMargin; |
621 | m_maxHeight += m_yMargin; | |
2a47d3c1 | 622 | |
8a0681f9 | 623 | SetSize(m_maxWidth, m_maxHeight); |
81d66cf3 | 624 | |
8a0681f9 VZ |
625 | return TRUE; |
626 | } | |
81d66cf3 | 627 | |
8a0681f9 | 628 | bool wxToolBar::InitGlobalObjects() |
2bda0e17 | 629 | { |
8a0681f9 VZ |
630 | GetSysColors(); |
631 | if (!CreateDitherBrush()) | |
632 | return FALSE; | |
2bda0e17 | 633 | |
8a0681f9 VZ |
634 | m_hdcMono = (WXHDC) CreateCompatibleDC(NULL); |
635 | if (!m_hdcMono) | |
636 | return FALSE; | |
2bda0e17 | 637 | |
8a0681f9 VZ |
638 | m_hbmMono = (WXHBITMAP) CreateBitmap((int)GetToolSize().x, (int)GetToolSize().y, 1, 1, NULL); |
639 | if (!m_hbmMono) | |
640 | return FALSE; | |
2bda0e17 | 641 | |
8a0681f9 VZ |
642 | m_hbmDefault = (WXHBITMAP) SelectObject((HDC) m_hdcMono, (HBITMAP) m_hbmMono); |
643 | return TRUE; | |
2bda0e17 KB |
644 | } |
645 | ||
8a0681f9 | 646 | void wxToolBar::FreeGlobalObjects() |
2bda0e17 KB |
647 | { |
648 | FreeDitherBrush(); | |
649 | ||
650 | if (m_hdcMono) { | |
8a0681f9 VZ |
651 | if (m_hbmDefault) |
652 | { | |
653 | SelectObject((HDC) m_hdcMono, (HBITMAP) m_hbmDefault); | |
654 | m_hbmDefault = 0; | |
655 | } | |
656 | DeleteDC((HDC) m_hdcMono); // toast the DCs | |
2bda0e17 KB |
657 | } |
658 | m_hdcMono = 0; | |
659 | ||
660 | if (m_hbmMono) | |
8a0681f9 | 661 | DeleteObject((HBITMAP) m_hbmMono); |
2bda0e17 KB |
662 | m_hbmMono = 0; |
663 | } | |
664 | ||
8a0681f9 VZ |
665 | // ---------------------------------------------------------------------------- |
666 | // drawing routines | |
667 | // ---------------------------------------------------------------------------- | |
2bda0e17 | 668 | |
8a0681f9 | 669 | void wxToolBar::PatB(WXHDC hdc,int x,int y,int dx,int dy, long rgb) |
2bda0e17 KB |
670 | { |
671 | RECT rc; | |
672 | ||
673 | rc.left = x; | |
674 | rc.top = y; | |
675 | rc.right = x + dx; | |
676 | rc.bottom = y + dy; | |
677 | ||
678 | SetBkColor((HDC) hdc,rgb); | |
679 | ExtTextOut((HDC) hdc,0,0,ETO_OPAQUE,&rc,NULL,0,NULL); | |
680 | } | |
681 | ||
682 | ||
683 | // create a mono bitmap mask: | |
684 | // 1's where color == COLOR_BTNFACE || COLOR_HILIGHT | |
685 | // 0's everywhere else | |
686 | ||
8a0681f9 | 687 | void wxToolBar::CreateMask(WXHDC hdc, int xoffset, int yoffset, int dx, int dy) |
2bda0e17 KB |
688 | { |
689 | HDC globalDC = ::GetDC(NULL); | |
690 | HDC hdcGlyphs = CreateCompatibleDC((HDC) globalDC); | |
691 | ReleaseDC(NULL, (HDC) globalDC); | |
692 | ||
693 | // krj - create a new bitmap and copy the image from hdc. | |
694 | //HBITMAP bitmapOld = SelectObject(hdcGlyphs, hBitmap); | |
695 | HBITMAP hBitmap = CreateCompatibleBitmap((HDC) hdc, dx, dy); | |
c4e7c2aa | 696 | HBITMAP bitmapOld = (HBITMAP) SelectObject(hdcGlyphs, hBitmap); |
2bda0e17 KB |
697 | BitBlt(hdcGlyphs, 0,0, dx, dy, (HDC) hdc, 0, 0, SRCCOPY); |
698 | ||
699 | // initalize whole area with 1's | |
700 | PatBlt((HDC) m_hdcMono, 0, 0, dx, dy, WHITENESS); | |
701 | ||
702 | // create mask based on color bitmap | |
703 | // convert this to 1's | |
704 | SetBkColor(hdcGlyphs, m_rgbFace); | |
81d66cf3 | 705 | BitBlt((HDC) m_hdcMono, xoffset, yoffset, (int)GetToolBitmapSize().x, (int)GetToolBitmapSize().y, |
2bda0e17 KB |
706 | hdcGlyphs, 0, 0, SRCCOPY); |
707 | // convert this to 1's | |
708 | SetBkColor(hdcGlyphs, m_rgbHilight); | |
709 | // OR in the new 1's | |
81d66cf3 | 710 | BitBlt((HDC) m_hdcMono, xoffset, yoffset, (int)GetToolBitmapSize().x, (int)GetToolBitmapSize().y, |
2bda0e17 KB |
711 | hdcGlyphs, 0, 0, SRCPAINT); |
712 | ||
713 | SelectObject(hdcGlyphs, bitmapOld); | |
714 | DeleteObject(hBitmap); | |
715 | DeleteDC(hdcGlyphs); | |
716 | } | |
717 | ||
8a0681f9 | 718 | void wxToolBar::DrawBlankButton(WXHDC hdc, int x, int y, int dx, int dy, int state) |
2bda0e17 KB |
719 | { |
720 | // face color | |
721 | PatB(hdc, x, y, dx, dy, m_rgbFace); | |
722 | ||
723 | if (state & wxTBSTATE_PRESSED) { | |
8a0681f9 VZ |
724 | PatB(hdc, x + 1, y, dx - 2, 1, m_rgbFrame); |
725 | PatB(hdc, x + 1, y + dy - 1, dx - 2, 1, m_rgbFrame); | |
726 | PatB(hdc, x, y + 1, 1, dy - 2, m_rgbFrame); | |
727 | PatB(hdc, x + dx - 1, y +1, 1, dy - 2, m_rgbFrame); | |
728 | PatB(hdc, x + 1, y + 1, 1, dy-2, m_rgbShadow); | |
729 | PatB(hdc, x + 1, y + 1, dx-2, 1, m_rgbShadow); | |
2bda0e17 KB |
730 | } |
731 | else { | |
8a0681f9 VZ |
732 | PatB(hdc, x + 1, y, dx - 2, 1, m_rgbFrame); |
733 | PatB(hdc, x + 1, y + dy - 1, dx - 2, 1, m_rgbFrame); | |
734 | PatB(hdc, x, y + 1, 1, dy - 2, m_rgbFrame); | |
735 | PatB(hdc, x + dx - 1, y + 1, 1, dy - 2, m_rgbFrame); | |
736 | dx -= 2; | |
737 | dy -= 2; | |
738 | PatB(hdc, x + 1, y + 1, 1, dy - 1, m_rgbHilight); | |
739 | PatB(hdc, x + 1, y + 1, dx - 1, 1, m_rgbHilight); | |
740 | PatB(hdc, x + dx, y + 1, 1, dy, m_rgbShadow); | |
741 | PatB(hdc, x + 1, y + dy, dx, 1, m_rgbShadow); | |
742 | PatB(hdc, x + dx - 1, y + 2, 1, dy - 2, m_rgbShadow); | |
743 | PatB(hdc, x + 2, y + dy - 1, dx - 2, 1, m_rgbShadow); | |
2bda0e17 KB |
744 | } |
745 | } | |
746 | ||
1dbe8708 VZ |
747 | void wxToolBar::DrawButton(WXHDC hdc, int x, int y, int dx, int dy, |
748 | wxToolBarToolBase *toolBase, int state) | |
2bda0e17 | 749 | { |
1dbe8708 VZ |
750 | wxToolBarTool *tool = (wxToolBarTool *)toolBase; |
751 | ||
2bda0e17 KB |
752 | int yOffset; |
753 | HBRUSH hbrOld, hbr; | |
754 | BOOL bMaskCreated = FALSE; | |
755 | int xButton = 0; // assume button is down | |
756 | int dxFace, dyFace; | |
757 | int xCenterOffset; | |
758 | ||
759 | dxFace = dx; | |
760 | dyFace = dy; | |
761 | ||
762 | // HBITMAP hBitmap = (HBITMAP) tool->m_bitmap1.GetHBITMAP(); | |
763 | HDC globalDC = ::GetDC(NULL); | |
764 | HDC hdcGlyphs = CreateCompatibleDC(globalDC); | |
765 | ReleaseDC(NULL, globalDC); | |
766 | ||
767 | // get the proper button look - up or down. | |
768 | if (!(state & (wxTBSTATE_PRESSED | wxTBSTATE_CHECKED))) { | |
769 | xButton = dx; // use 'up' version of button | |
770 | dxFace -= 2; | |
771 | dyFace -= 2; // extents to ignore button highlight | |
772 | } | |
773 | ||
774 | DrawBlankButton(hdc, x, y, dx, dy, state); | |
775 | ||
776 | ||
777 | // move coordinates inside border and away from upper left highlight. | |
778 | // the extents change accordingly. | |
779 | x += 2; | |
780 | y += 2; | |
781 | dxFace -= 3; | |
782 | dyFace -= 3; | |
783 | ||
a3399e6c | 784 | // Using bmpDisabled can cause problems (don't know why!) |
2bda0e17 KB |
785 | #if !defined(__WIN32__) && !defined(__WIN386__) |
786 | HBITMAP bitmapOld; | |
8a0681f9 VZ |
787 | if (tool->GetBitmap2().Ok()) |
788 | bitmapOld = GetHbitmapOf(tool->GetBitmap2()); | |
2bda0e17 | 789 | else |
8a0681f9 | 790 | bitmapOld = GetHbitmapOf(tool->GetBitmap1()); |
2bda0e17 | 791 | #else |
8a0681f9 | 792 | HBITMAP bitmapOld = GetHbitmapOf(tool->GetBitmap1()); |
2bda0e17 KB |
793 | #endif |
794 | ||
8a0681f9 VZ |
795 | bitmapOld = (HBITMAP)SelectObject(hdcGlyphs, bitmapOld); |
796 | ||
2bda0e17 KB |
797 | // calculate offset of face from (x,y). y is always from the top, |
798 | // so the offset is easy. x needs to be centered in face. | |
799 | yOffset = 1; | |
81d66cf3 | 800 | xCenterOffset = (dxFace - (int)GetToolBitmapSize().x)/2; |
2bda0e17 KB |
801 | if (state & (wxTBSTATE_PRESSED | wxTBSTATE_CHECKED)) |
802 | { | |
803 | // pressed state moves down and to the right | |
804 | // (x moves automatically as face size grows) | |
805 | yOffset++; | |
806 | } | |
807 | ||
808 | // now put on the face | |
809 | if (state & wxTBSTATE_ENABLED) { | |
810 | // regular version | |
81d66cf3 | 811 | BitBlt((HDC) hdc, x+xCenterOffset, y + yOffset, (int)GetToolBitmapSize().x, (int)GetToolBitmapSize().y, |
2bda0e17 KB |
812 | hdcGlyphs, 0, 0, SRCCOPY); |
813 | } else { | |
814 | // disabled version (or indeterminate) | |
815 | bMaskCreated = TRUE; | |
816 | CreateMask((WXHDC) hdcGlyphs, xCenterOffset, yOffset, dxFace, dyFace); | |
817 | // CreateMask(hBitmap, xCenterOffset, yOffset, dxFace, dyFace); | |
818 | ||
819 | SetTextColor((HDC) hdc, 0L); // 0's in mono -> 0 (for ROP) | |
820 | SetBkColor((HDC) hdc, 0x00FFFFFF); // 1's in mono -> 1 | |
821 | ||
822 | // draw glyph's white understrike | |
823 | if (!(state & wxTBSTATE_INDETERMINATE)) { | |
824 | hbr = CreateSolidBrush(m_rgbHilight); | |
825 | if (hbr) { | |
c4e7c2aa | 826 | hbrOld = (HBRUSH) SelectObject((HDC) hdc, hbr); |
2bda0e17 KB |
827 | if (hbrOld) { |
828 | // draw hilight color where we have 0's in the mask | |
829 | BitBlt((HDC) hdc, x + 1, y + 1, dxFace, dyFace, (HDC) m_hdcMono, 0, 0, 0x00B8074A); | |
830 | SelectObject((HDC) hdc, hbrOld); | |
831 | } | |
832 | DeleteObject(hbr); | |
833 | } | |
834 | } | |
835 | ||
836 | // gray out glyph | |
837 | hbr = CreateSolidBrush(m_rgbShadow); | |
838 | if (hbr) { | |
c4e7c2aa | 839 | hbrOld = (HBRUSH) SelectObject((HDC) hdc, hbr); |
2bda0e17 KB |
840 | if (hbrOld) { |
841 | // draw the shadow color where we have 0's in the mask | |
842 | BitBlt((HDC) hdc, x, y, dxFace, dyFace, (HDC) m_hdcMono, 0, 0, 0x00B8074A); | |
843 | SelectObject((HDC) hdc, hbrOld); | |
844 | } | |
845 | DeleteObject(hbr); | |
846 | } | |
847 | ||
848 | if (state & wxTBSTATE_CHECKED) { | |
849 | BitBlt((HDC) m_hdcMono, 1, 1, dxFace - 1, dyFace - 1, (HDC) m_hdcMono, 0, 0, SRCAND); | |
850 | } | |
851 | } | |
852 | ||
853 | if (state & (wxTBSTATE_CHECKED | wxTBSTATE_INDETERMINATE)) { | |
854 | ||
c4e7c2aa | 855 | hbrOld = (HBRUSH) SelectObject((HDC) hdc, (HBRUSH) m_hbrDither); |
2bda0e17 KB |
856 | if (hbrOld) { |
857 | ||
858 | if (!bMaskCreated) | |
859 | CreateMask((WXHDC) hdcGlyphs, xCenterOffset, yOffset, dxFace, dyFace); | |
860 | // CreateMask(hBitmap, xCenterOffset, yOffset, dxFace, dyFace); | |
861 | ||
862 | SetTextColor((HDC) hdc, 0L); // 0 -> 0 | |
863 | SetBkColor((HDC) hdc, 0x00FFFFFF); // 1 -> 1 | |
864 | ||
865 | // only draw the dither brush where the mask is 1's | |
866 | BitBlt((HDC) hdc, x, y, dxFace, dyFace, (HDC) m_hdcMono, 0, 0, 0x00E20746); | |
867 | ||
868 | SelectObject((HDC) hdc, hbrOld); | |
869 | } | |
870 | } | |
871 | SelectObject(hdcGlyphs, bitmapOld); | |
872 | DeleteDC(hdcGlyphs); | |
873 | } | |
874 | ||
8a0681f9 VZ |
875 | // ---------------------------------------------------------------------------- |
876 | // drawing helpers | |
877 | // ---------------------------------------------------------------------------- | |
878 | ||
879 | void wxToolBar::GetSysColors() | |
2bda0e17 KB |
880 | { |
881 | static COLORREF rgbSaveFace = 0xffffffffL, | |
882 | rgbSaveShadow = 0xffffffffL, | |
883 | rgbSaveHilight = 0xffffffffL, | |
884 | rgbSaveFrame = 0xffffffffL; | |
885 | ||
886 | // For now, override these because the colour replacement isn't working, | |
887 | // and we get inconsistent colours. Assume all buttons are grey for the moment. | |
888 | ||
889 | // m_rgbFace = GetSysColor(COLOR_BTNFACE); | |
890 | m_rgbFace = RGB(192,192,192); | |
891 | // m_rgbShadow = GetSysColor(COLOR_BTNSHADOW); | |
892 | m_rgbShadow = RGB(128,128,128); | |
893 | // m_rgbHilight = GetSysColor(COLOR_BTNHIGHLIGHT); | |
894 | m_rgbHilight = RGB(255, 255, 255); | |
895 | ||
896 | m_rgbFrame = GetSysColor(COLOR_WINDOWFRAME); | |
897 | ||
898 | if (rgbSaveFace!=m_rgbFace || rgbSaveShadow!=m_rgbShadow | |
899 | || rgbSaveHilight!=m_rgbHilight || rgbSaveFrame!=m_rgbFrame) | |
900 | { | |
901 | rgbSaveFace = m_rgbFace; | |
902 | rgbSaveShadow = m_rgbShadow; | |
903 | rgbSaveHilight = m_rgbHilight; | |
904 | rgbSaveFrame = m_rgbFrame; | |
905 | ||
906 | // Update the brush for pushed-in buttons | |
907 | CreateDitherBrush(); | |
908 | } | |
909 | } | |
910 | ||
8a0681f9 | 911 | WXHBITMAP wxToolBar::CreateDitherBitmap() |
2bda0e17 KB |
912 | { |
913 | BITMAPINFO* pbmi; | |
914 | HBITMAP hbm; | |
915 | HDC hdc; | |
916 | int i; | |
917 | long patGray[8]; | |
918 | DWORD rgb; | |
919 | ||
920 | pbmi = (BITMAPINFO *)malloc(sizeof(BITMAPINFOHEADER) + 16*sizeof(RGBQUAD)); | |
921 | memset(pbmi, 0, (sizeof(BITMAPINFOHEADER) + 16*sizeof(RGBQUAD))); | |
922 | ||
923 | pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); | |
924 | pbmi->bmiHeader.biWidth = 8; | |
925 | pbmi->bmiHeader.biHeight = 8; | |
926 | pbmi->bmiHeader.biPlanes = 1; | |
927 | pbmi->bmiHeader.biBitCount = 1; | |
928 | pbmi->bmiHeader.biCompression = BI_RGB; | |
929 | ||
930 | // rgb = GetSysColor(COLOR_BTNFACE); | |
931 | rgb = RGB(192,192,192); | |
932 | ||
933 | pbmi->bmiColors[0].rgbBlue = GetBValue(rgb); | |
934 | pbmi->bmiColors[0].rgbGreen = GetGValue(rgb); | |
935 | pbmi->bmiColors[0].rgbRed = GetRValue(rgb); | |
936 | pbmi->bmiColors[0].rgbReserved = 0; | |
937 | ||
938 | // rgb = GetSysColor(COLOR_BTNHIGHLIGHT); | |
939 | rgb = RGB(255, 255, 255); | |
940 | ||
941 | pbmi->bmiColors[1].rgbBlue = GetBValue(rgb); | |
942 | pbmi->bmiColors[1].rgbGreen = GetGValue(rgb); | |
943 | pbmi->bmiColors[1].rgbRed = GetRValue(rgb); | |
944 | pbmi->bmiColors[1].rgbReserved = 0; | |
945 | ||
946 | /* initialize the brushes */ | |
947 | ||
948 | for (i = 0; i < 8; i++) | |
949 | if (i & 1) | |
950 | patGray[i] = 0xAAAA5555L; // 0x11114444L; // lighter gray | |
951 | else | |
952 | patGray[i] = 0x5555AAAAL; // 0x11114444L; // lighter gray | |
953 | ||
954 | hdc = ::GetDC(NULL); | |
955 | ||
956 | hbm = CreateDIBitmap(hdc, &pbmi->bmiHeader, CBM_INIT, patGray, pbmi, DIB_RGB_COLORS); | |
957 | ||
958 | ReleaseDC(NULL, hdc); | |
959 | free(pbmi); | |
960 | ||
961 | return (WXHBITMAP)hbm; | |
962 | } | |
963 | ||
8a0681f9 | 964 | bool wxToolBar::CreateDitherBrush() |
2bda0e17 KB |
965 | { |
966 | HBITMAP hbmGray; | |
967 | HBRUSH hbrSave; | |
968 | if (m_hbrDither) | |
969 | return TRUE; | |
970 | hbmGray = (HBITMAP) CreateDitherBitmap(); | |
971 | ||
972 | if (hbmGray) | |
973 | { | |
974 | hbrSave = (HBRUSH) m_hbrDither; | |
975 | m_hbrDither = (WXHBRUSH) CreatePatternBrush(hbmGray); | |
976 | DeleteObject(hbmGray); | |
977 | if (m_hbrDither) | |
978 | { | |
979 | if (hbrSave) | |
980 | { | |
981 | DeleteObject(hbrSave); | |
982 | } | |
983 | return TRUE; | |
984 | } | |
985 | else | |
986 | { | |
987 | m_hbrDither = (WXHBRUSH) hbrSave; | |
988 | } | |
989 | } | |
990 | ||
991 | return FALSE; | |
992 | } | |
993 | ||
8a0681f9 | 994 | bool wxToolBar::FreeDitherBrush(void) |
2bda0e17 KB |
995 | { |
996 | if (m_hbrDither) | |
997 | DeleteObject((HBRUSH) m_hbrDither); | |
998 | m_hbrDither = 0; | |
999 | return TRUE; | |
1000 | } | |
1001 | ||
1002 | typedef struct tagCOLORMAP2 | |
1003 | { | |
1004 | COLORREF bgrfrom; | |
1005 | COLORREF bgrto; | |
1006 | COLORREF sysColor; | |
1007 | } COLORMAP2; | |
1008 | ||
1009 | // these are the default colors used to map the dib colors | |
1010 | // to the current system colors | |
1011 | ||
1012 | #define BGR_BUTTONTEXT (RGB(000,000,000)) // black | |
1013 | #define BGR_BUTTONSHADOW (RGB(128,128,128)) // dark grey | |
1014 | #define BGR_BUTTONFACE (RGB(192,192,192)) // bright grey | |
1015 | #define BGR_BUTTONHILIGHT (RGB(255,255,255)) // white | |
8a0681f9 | 1016 | #define BGR_BACKGROUNDSEL (RGB(255,000,000)) // blue |
2bda0e17 KB |
1017 | #define BGR_BACKGROUND (RGB(255,000,255)) // magenta |
1018 | #define FlipColor(rgb) (RGB(GetBValue(rgb), GetGValue(rgb), GetRValue(rgb))) | |
1019 | ||
8a0681f9 | 1020 | WXHBITMAP wxToolBar::CreateMappedBitmap(WXHINSTANCE WXUNUSED(hInstance), void *info) |
2bda0e17 KB |
1021 | { |
1022 | LPBITMAPINFOHEADER lpBitmapInfo = (LPBITMAPINFOHEADER)info; | |
1023 | HDC hdc, hdcMem = NULL; | |
1024 | ||
1025 | DWORD FAR *p; | |
1026 | LPSTR lpBits; | |
1027 | HBITMAP hbm = NULL, hbmOld; | |
1028 | int numcolors, i; | |
1029 | int wid, hgt; | |
1030 | static COLORMAP2 ColorMap[] = { | |
1031 | {BGR_BUTTONTEXT, BGR_BUTTONTEXT, COLOR_BTNTEXT}, // black | |
1032 | {BGR_BUTTONSHADOW, BGR_BUTTONSHADOW, COLOR_BTNSHADOW}, // dark grey | |
1033 | {BGR_BUTTONFACE, BGR_BUTTONFACE, COLOR_BTNFACE}, // bright grey | |
1034 | {BGR_BUTTONHILIGHT, BGR_BUTTONHILIGHT, COLOR_BTNHIGHLIGHT},// white | |
1035 | {BGR_BACKGROUNDSEL, BGR_BACKGROUNDSEL, COLOR_HIGHLIGHT}, // blue | |
1036 | {BGR_BACKGROUND, BGR_BACKGROUND, COLOR_WINDOW} // magenta | |
1037 | }; | |
1038 | ||
1039 | #define NUM_MAPS (sizeof(ColorMap)/sizeof(COLORMAP2)) | |
1040 | ||
1041 | if (!lpBitmapInfo) | |
1042 | return 0; | |
1043 | ||
1044 | // | |
1045 | // So what are the new colors anyway ? | |
1046 | // | |
1047 | for (i=0; i < (int) NUM_MAPS; i++) { | |
1048 | ColorMap[i].bgrto = (long unsigned int) FlipColor(GetSysColor((int)ColorMap[i].sysColor)); | |
1049 | } | |
1050 | ||
1051 | p = (DWORD FAR *)(((LPSTR)lpBitmapInfo) + lpBitmapInfo->biSize); | |
1052 | ||
1053 | /* Replace button-face and button-shadow colors with the current values | |
1054 | */ | |
1055 | numcolors = 16; | |
1056 | ||
1057 | while (numcolors-- > 0) { | |
1058 | for (i = 0; i < (int) NUM_MAPS; i++) { | |
1059 | if (*p == ColorMap[i].bgrfrom) { | |
1060 | *p = ColorMap[i].bgrto; | |
1061 | break; | |
1062 | } | |
1063 | } | |
1064 | p++; | |
1065 | } | |
1066 | ||
1067 | /* First skip over the header structure */ | |
1068 | lpBits = (LPSTR)(lpBitmapInfo + 1); | |
1069 | ||
1070 | /* Skip the color table entries, if any */ | |
1071 | lpBits += (1 << (lpBitmapInfo->biBitCount)) * sizeof(RGBQUAD); | |
1072 | ||
1073 | /* Create a color bitmap compatible with the display device */ | |
1074 | i = wid = (int)lpBitmapInfo->biWidth; | |
1075 | hgt = (int)lpBitmapInfo->biHeight; | |
1076 | hdc = ::GetDC(NULL); | |
1077 | ||
1078 | hdcMem = CreateCompatibleDC(hdc); | |
1079 | if (hdcMem) { | |
1080 | // hbm = CreateDiscardableBitmap(hdc, i, hgt); | |
1081 | hbm = CreateCompatibleBitmap(hdc, i, hgt); | |
1082 | if (hbm) { | |
c4e7c2aa | 1083 | hbmOld = (HBITMAP) SelectObject(hdcMem, hbm); |
2bda0e17 KB |
1084 | |
1085 | // set the main image | |
1086 | StretchDIBits(hdcMem, 0, 0, wid, hgt, 0, 0, wid, hgt, lpBits, | |
1087 | (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS, SRCCOPY); | |
1088 | ||
1089 | SelectObject(hdcMem, hbmOld); | |
1090 | } | |
1091 | ||
1092 | DeleteObject(hdcMem); | |
1093 | } | |
1094 | ||
1095 | ReleaseDC(NULL, hdc); | |
1096 | ||
1097 | return (WXHBITMAP) hbm; | |
1098 | } | |
1099 | ||
8a0681f9 | 1100 | WXHBITMAP wxToolBar::CreateMappedBitmap(WXHINSTANCE hInstance, WXHBITMAP hBitmap) |
2bda0e17 | 1101 | { |
2b254edf VZ |
1102 | HANDLE hDIB = wxDIB::ConvertFromBitmap((HBITMAP) hBitmap); |
1103 | if ( !hDIB ) | |
1104 | return 0; | |
1105 | ||
06d09389 | 1106 | WXHBITMAP newBitmap = CreateMappedBitmap(hInstance, GlobalPtr(hDIB)); |
2b254edf | 1107 | |
2bda0e17 | 1108 | GlobalFree(hDIB); |
2b254edf VZ |
1109 | |
1110 | return newBitmap; | |
2bda0e17 KB |
1111 | } |
1112 | ||
2b254edf VZ |
1113 | #endif // wxUSE_TOOLBAR |
1114 |