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