6 * Portable Windows Library
8 * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
10 * The contents of this file are subject to the Mozilla Public License
11 * Version 1.0 (the "License"); you may not use this file except in
12 * compliance with the License. You may obtain a copy of the License at
13 * http://www.mozilla.org/MPL/
15 * Software distributed under the License is distributed on an "AS IS"
16 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17 * the License for the specific language governing rights and limitations
20 * The Original Code is Portable Windows Library.
22 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
24 * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
25 * All Rights Reserved.
27 * Contributor(s): ______________________________________.
30 * Revision 1.43 1998/12/20 09:14:39 robertj
31 * Added pragma implementation for GNU compiler.
33 * Revision 1.42 1998/11/30 04:52:14 robertj
34 * New directory structure
36 * Revision 1.41 1998/10/13 14:06:35 robertj
37 * Complete rewrite of memory leak detection code.
39 * Revision 1.40 1998/09/23 06:29:35 robertj
40 * Added open source copyright license.
42 * Revision 1.39 1996/07/15 10:34:03 robertj
43 * Fixed uninitialised variable.
45 * Revision 1.38 1996/06/10 11:28:27 robertj
46 * Changes for better C++ compatibility.
48 * Revision 1.37 1996/04/30 12:33:48 robertj
49 * Changed "inPixels" boolean to enum for three coordinate systems.
51 * Revision 1.36 1995/10/14 15:06:56 robertj
52 * Fixed bug in changing fonts on status bar.
54 * Revision 1.35 1995/08/12 22:32:43 robertj
55 * Fixed setting of foreground/background colours with adjusted DrawBevelledRect().
57 * Revision 1.34 1995/07/31 12:13:01 robertj
58 * Added balloon help string to toolbar button codes.
60 * Revision 1.33 1995/06/04 12:38:24 robertj
61 * Redesign to add vertical tool bars and control wrapping.
63 * Revision 1.32 1995/04/25 11:28:13 robertj
64 * Fixed Borland compiler warnings.
66 * Revision 1.31 1995/04/03 11:21:31 robertj
67 * Fixed SetSectionText.
69 * Revision 1.30 1995/04/02 09:27:26 robertj
70 * Added "balloon" help.
72 * Revision 1.29 1995/03/22 13:50:58 robertj
73 * Split SetText() to separate function for SetSectionText() to guarentee that
74 * the parameters can be resolved.
76 * Revision 1.28 1995/02/19 04:19:19 robertj
77 * Added dynamically linked command processing.
79 * Revision 1.27 1995/01/21 05:20:54 robertj
80 * Allowed callback functions on button bar buttons.
81 * Made disabled icon default to enabled icon.
83 * Revision 1.26 1995/01/18 09:04:23 robertj
84 * Added initialiser arrays for button bar and status bar.
86 * Revision 1.25 1995/01/15 04:53:08 robertj
87 * Fixed problems with stdarg and PString parameter on GNU compiler.
89 * Revision 1.24 1995/01/10 11:44:12 robertj
90 * Removed PString parameter in stdarg function for GNU C++ compatibility.
92 * Revision 1.23 1995/01/06 10:43:55 robertj
93 * Changed PRealFont usage from pointer to reference.
95 * Revision 1.22 1994/12/14 11:17:14 robertj
96 * Changed PDIMENSION to be unsigned causing untold number of changes.
98 * Revision 1.21 1994/11/28 23:30:21 robertj
99 * Added Update() call whenever a status bar section text is changed.
101 * Revision 1.21 1994/11/28 12:44:37 robertj
102 * Added Update() after a change of status bar text to guarentee that it is visible at
103 * the time of setting. But only if the string changes!
105 * Revision 1.20 1994/10/30 11:47:10 robertj
106 * Changed mechanism for doing notification callback functions.
108 * Revision 1.19 1994/08/21 23:43:02 robertj
109 * Changed parameter before variable argument list to NOT be a reference.
111 * Revision 1.18 1994/08/15 07:02:42 robertj
112 * Optimised status bar with transparent text display.
114 * Revision 1.17 1994/08/01 03:41:24 robertj
115 * Use of PNEW instead of new for heap debugging. Need undef for Unix end.
117 * Revision 1.16 1994/07/27 05:58:07 robertj
120 * Revision 1.15 1994/06/25 11:55:15 robertj
121 * Unix version synchronisation.
123 * Revision 1.14 1994/04/20 12:17:44 robertj
126 * Revision 1.13 1994/04/01 14:00:00 robertj
127 * Fixed SetDimensions change bug
130 * Revision 1.12 1994/03/07 07:47:00 robertj
133 * Revision 1.11 1994/01/15 02:52:02 robertj
134 * Mac compatibilty changes (no nested classes).
136 * Revision 1.10 1994/01/13 03:36:48 robertj
137 * Created intermediate class PInteractorLayout for dialog-ish windows.
139 * Revision 1.9 1994/01/03 10:17:10 robertj
140 * Changed IsAncestor mechanism.
143 * Revision 1.8 1993/12/31 06:49:35 robertj
144 * Added PImgIcon class.
146 * Revision 1.7 1993/12/04 05:21:59 robertj
147 * Moved code from pwlib.inl
149 * Revision 1.6 1993/12/01 16:09:05 robertj
152 * Revision 1.5 1993/11/20 17:26:28 robertj
153 * Change of button picture from PImage to PPixels
155 * Revision 1.4 1993/08/27 18:17:47 robertj
156 * Fixed bars code to use the new canvas function for drawing bevelled areas.
158 * Revision 1.3 1993/08/21 17:09:50 robertj
159 * Added checking of enabled menu in button bar selections.
160 * Fixed problem with G++ compatibility in temprary string object creation.
162 * Revision 1.2 1993/08/21 01:50:33 robertj
163 * Made Clone() function optional, default will assert if called.
165 * Revision 1.1 1993/08/21 01:07:35 robertj
171 #pragma implementation "toolbars.h"
175 #include <pwclib/toolbars.h>
180 //////////////////////////////////////////////////////////////////////////////
183 PToolBar::PToolBar(PInteractor
* parent
, BOOL vertical
, BOOL autoWrap
)
184 : PInteractorLayout(parent
),
185 positionDown(vertical
),
186 wrapControls(autoWrap
)
188 margin
= owner
->GetBorderSize()*3;
190 margin
.SetHeight(margin
.Height()*2);
192 margin
.SetWidth(margin
.Width()*2);
193 SetForegroundColour(owner
->GetButtonFgColour());
194 SetBackgroundColour(owner
->GetButtonBkColour());
198 void PToolBar::OnRedraw(PCanvas
& canvas
)
200 canvas
.SetMappingRect(canvas
.GetViewportRect());
201 PRect bounds
= canvas
.GetDrawingBounds();
202 canvas
.DrawBevelledRect(bounds
, TRUE
, FALSE
);
206 PBalloon
* PToolBar::OnBalloonHelp()
208 return owner
->DoBalloonHelp(NULL
, 2);
212 void PToolBar::AddControl(PControl
* control
,
213 PDIMENSION gapSize
, PDIMENSION elasticity
)
215 item
.Append(new BarItem(PAssertNULL(control
), gapSize
, elasticity
));
217 PDim myDim
= GetDimensions(PixelCoords
);
218 PDim ctlDim
= control
->GetDimensions(PixelCoords
);
222 if (ctlDim
.Width() > myDim
.Width())
223 myDim
.SetWidth(ctlDim
.Width());
225 if (ctlDim
.Height() > myDim
.Height())
226 myDim
.SetHeight(ctlDim
.Height());
228 SetDimensions(myDim
.Width(), myDim
.Height(), PixelCoords
);
232 void PToolBar::_SetDimensions(PDIMENSION width
, PDIMENSION height
,
233 CoordinateSystem coords
)
235 PInteractorLayout::_SetDimensions(width
, height
, coords
);
240 void PToolBar::DoControlGeometry()
242 PDim myDim
= GetDimensions(PixelCoords
);
243 PDIMENSION barSize
= positionDown
? myDim
.Height() : myDim
.Width();
244 PDIMENSION marginSize
= positionDown
? margin
.Height() : margin
.Width();
246 PDIMENSION maxSize
= 0;
247 PDIMENSION fixedSize
= 0;
248 PDIMENSION propTotal
= 0;
250 for (i
= 0; i
< item
.GetSize(); i
++) {
251 PDim ctlDim
= item
[i
].control
->GetDimensions(PixelCoords
);
252 if (item
[i
].elasticity
> 0)
253 propTotal
+= item
[i
].elasticity
;
255 fixedSize
+= positionDown
? ctlDim
.Height() : ctlDim
.Width();
256 fixedSize
+= item
[i
].gapSize
*marginSize
;
258 if (maxSize
< ctlDim
.Width())
259 maxSize
= ctlDim
.Width();
262 if (maxSize
< ctlDim
.Height())
263 maxSize
= ctlDim
.Height();
267 PDIMENSION elasticUnit
= 0;
269 elasticUnit
= (barSize
- fixedSize
- marginSize
*2)/propTotal
;
270 if (elasticUnit
< 10)
274 PPoint ctlPos
= margin
;
275 for (i
= 0; i
< item
.GetSize(); i
++) {
276 PDim ctlDim
= item
[i
].control
->GetDimensions(PixelCoords
);
278 if (item
[i
].elasticity
> 0) {
280 ctlDim
.SetHeight(item
[i
].elasticity
*elasticUnit
);
282 ctlDim
.SetWidth(item
[i
].elasticity
*elasticUnit
);
283 item
[i
].control
->SetDimensions(ctlDim
, PixelCoords
);
288 if (ctlPos
.Y() + ctlDim
.Height() > myDim
.Height()) {
289 ctlPos
.SetX(maxSize
+ margin
.Width());
290 ctlPos
.SetY(margin
.Height());
294 if (ctlPos
.X() + ctlDim
.Width() > myDim
.Width()) {
295 ctlPos
.SetX(margin
.Width());
296 ctlPos
.SetY(maxSize
+ margin
.Height());
301 item
[i
].control
->SetPosition(ctlPos
, TopLeftPixels
, TopLeftPixels
);
304 ctlPos
.SetY(ctlPos
.Y() + ctlDim
.Height() + item
[i
].gapSize
*marginSize
);
306 ctlPos
.SetX(ctlPos
.X() + ctlDim
.Width() + item
[i
].gapSize
*marginSize
);
311 //////////////////////////////////////////////////////////////////////////////
314 PButtonBar::PButtonBar(PInteractor
*parent
,
315 const ButtonID
*IDs
, PINDEX numIDs
, BOOL vertical
, BOOL autoWrap
)
316 : PToolBar(parent
, vertical
, autoWrap
)
318 AddButtons(IDs
, numIDs
);
322 void PButtonBar::AddButtons(const ButtonID
* IDs
, PINDEX numIDs
)
324 // Calculate the maximum button size so far in bar.
325 PDIMENSION max_x
= 0;
326 PDIMENSION max_y
= 0;
328 for (i
= 0; i
< GetNumChildren(); i
++) {
329 if (children
[i
].IsDescendant(PImageButton::Class())) {
330 PDim dim
= children
[i
].GetDimensions(PixelCoords
);
331 if (max_x
< dim
.Width())
333 if (max_y
< dim
.Height())
334 max_y
= dim
.Height();
338 // Add in the new buttons, increasing the maximum size
339 for (i
= 0; i
< numIDs
; i
++) {
340 if (IDs
[i
].commandName
!= NULL
|| IDs
[i
].menuItem
!= 0) {
341 PRESOURCE_ID img1
= IDs
[i
].enabledImage
;
343 img1
= IDs
[i
].menuItem
;
344 PRESOURCE_ID img2
= IDs
[i
].disabledImage
;
348 PPushButton
* button
;
350 button
= new PImageButton(this, PImgIcon(img1
), PImgIcon(img2
));
352 button
= new PImageButton(this);
354 button
->SetControlID(IDs
[i
].menuItem
);
356 if (IDs
[i
].commandName
!= NULL
)
357 button
->SetNotifier(PCREATE_COMMAND(IDs
[i
].commandName
), TRUE
);
359 PRESOURCE_ID help
= IDs
[i
].balloonHelp
;
361 help
= IDs
[i
].menuItem
;
363 PResourceString
str(help
);
364 button
->SetBalloonHelp(str
);
369 PDim dim
= button
->GetDimensions(PixelCoords
);
370 if (max_x
< dim
.Width())
372 if (max_y
< dim
.Height())
373 max_y
= dim
.Height();
377 for (i
= 0; i
< numIDs
; i
++) {
378 if (IDs
[i
].commandName
!= NULL
|| IDs
[i
].menuItem
!= 0) {
379 PControl
* button
= GetControl(IDs
[i
].menuItem
);
380 PAssertNULL(button
)->SetDimensions(max_x
, max_y
, PixelCoords
);
382 while (i
+gaps
< numIDs
&&
383 (IDs
[i
+gaps
].commandName
== NULL
&& IDs
[i
+gaps
].menuItem
== 0))
385 AddControl(button
, gaps
-1);
391 void PButtonBar::OnControlNotify(PControl
& control
, int code
)
393 PInteractorLayout::OnControlNotify(control
, code
);
395 if (control
.GetNotifier().IsNULL()) {
396 PInteractor
* p
= parent
;
397 while (p
->GetParent() != NULL
)
399 PTopLevelWindow
* mainWindow
= (PTopLevelWindow
*)p
;
400 mainWindow
->OnMenuStartSelect();
401 PRootMenu
* menu
= mainWindow
->GetMenu();
403 PMenuItem
* item
= menu
->GetItemFromKey(control
.GetControlID());
404 if (item
!= NULL
&& item
->IsEnabled())
405 mainWindow
->OnMenuItemSelect(*item
);
412 //////////////////////////////////////////////////////////////////////////////
415 PStatusBar::PStatusBar(PInteractor
* parent
, PINDEX numSections
)
419 parent
->GetDimensions(PixelCoords
).Width()/numSections
- margin
.Width();
420 PDIMENSION height
= font
.GetHeight(TRUE
) + margin
.Height();
421 for (PINDEX i
= 0; i
< numSections
; i
++) {
422 Section
* s
= new Section(this);
423 s
->SetDimensions(width
, height
, PixelCoords
);
424 AddControl(s
, i
< numSections
-1, 1);
429 void PStatusBar::SetFont(const PFont
& newFont
, BOOL toChildren
)
431 PToolBar::SetFont(newFont
, toChildren
);
433 PDIMENSION height
= font
.GetHeight(TRUE
) + margin
.Height();
434 for (PINDEX i
= 0; i
< item
.GetSize(); i
++)
435 item
[i
].control
->SetDimensions(1, height
, PixelCoords
);
439 height
+= margin
.Height()*2;
440 SetDimensions(GetDimensions(ScreenCoords
).Width(), height
, PixelCoords
);
444 void PStatusBar::SetText(const PString
& str
)
446 SetSectionText(0, str
);
450 void PStatusBar::SetText(PRESOURCE_ID resId
, ...)
453 va_start(args
, resId
);
455 PResourceString
fmt(resId
);
456 str
.vsprintf(fmt
, args
);
457 SetSectionText(0, str
);
461 void PStatusBar::SetText(const char * fmt
, ...)
466 str
.vsprintf(fmt
, args
);
467 SetSectionText(0, str
);
471 void PStatusBar::SetSectionText(PINDEX section
, const PString
& str
)
473 Section
& s
= GetSection(section
);
474 if (s
.GetName() != str
) {
481 void PStatusBar::SetSectionText(PINDEX section
, PRESOURCE_ID resId
, ...)
484 va_start(args
, resId
);
485 PResourceString
fmt(resId
);
486 SetSectionText(section
, pvsprintf(fmt
, args
));
490 void PStatusBar::SetSectionText(PINDEX section
, const char * fmt
, ...)
494 SetSectionText(section
, pvsprintf(fmt
, args
));
498 void PStatusBar::SetSectionAlignment(PINDEX section
,
499 PCanvas::DrawStringOptions align
)
501 GetSection(section
).SetAlignment(align
);
505 void PStatusBar::SetSectionWidth(PINDEX section
, const PString
& longestString
)
507 SetSectionWidth(section
,
508 PDrawCanvas(this).MeasureString(longestString
).Width());
512 void PStatusBar::SetSectionWidth(PINDEX section
,
513 const PRESOURCE_ID
* strIDs
, PINDEX nStrings
)
515 PDrawCanvas
canvas(this);
517 for (PINDEX i
= 0; i
< nStrings
; i
++) {
518 PDIMENSION width
=canvas
.MeasureString(PResourceString(strIDs
[i
])).Width();
522 SetSectionWidth(section
, max
);
526 void PStatusBar::SetSectionWidth(PINDEX section
, int width
)
528 Section
& s
= GetSection(section
);
531 s
.SetDimensions(width
, s
.GetDimensions(LocalCoords
).Height(), LocalCoords
);
533 item
[section
].elasticity
= width
< 0 ? -width
: 0;
535 SetDimensions(GetDimensions(LocalCoords
), LocalCoords
);
539 PStatusBar::Section
& PStatusBar::GetSection(PINDEX section
) const
541 PInteractor
& s
= *item
[section
].control
;
542 PAssert(s
.IsDescendant(Section::Class()), PInvalidParameter
);
547 PStatusBar::Section::Section(PInteractor
* parent
)
548 : PStaticText(parent
)
550 SetBackgroundColour(owner
->GetButtonBkColour());
555 void PStatusBar::Section::OnRedraw(PCanvas
& canvas
)
557 canvas
.SetMappingRect(canvas
.GetViewportRect());
558 PRect bounds
= canvas
.GetDrawingBounds();
559 canvas
.DrawBevelledRect(bounds
, FALSE
, FALSE
);
560 bounds
.Inflate(-1, -1);
561 canvas
.SetTextFgColour(owner
->GetButtonFgColour());
562 canvas
.SetTextBkColour(PColour(0,0,0,0));
563 canvas
.DrawString(bounds
, GetName(), alignment
);
567 // End Of File ///////////////////////////////////////////////////////////////