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