bars.cxx
上传用户:hzhsqp
上传日期:2007-01-06
资源大小:1600k
文件大小:16k
源码类别:

IP电话/视频会议

开发平台:

Visual C++

  1. /*
  2.  * bars.cxx
  3.  *
  4.  * Tool bar classes.
  5.  *
  6.  * Portable Windows Library
  7.  *
  8.  * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
  9.  *
  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/
  14.  *
  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
  18.  * under the License.
  19.  *
  20.  * The Original Code is Portable Windows Library.
  21.  *
  22.  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
  23.  *
  24.  * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
  25.  * All Rights Reserved.
  26.  *
  27.  * Contributor(s): ______________________________________.
  28.  *
  29.  * $Log: bars.cxx,v $
  30.  * Revision 1.43  1998/12/20 09:14:39  robertj
  31.  * Added pragma implementation for GNU compiler.
  32.  *
  33.  * Revision 1.42  1998/11/30 04:52:14  robertj
  34.  * New directory structure
  35.  *
  36.  * Revision 1.41  1998/10/13 14:06:35  robertj
  37.  * Complete rewrite of memory leak detection code.
  38.  *
  39.  * Revision 1.40  1998/09/23 06:29:35  robertj
  40.  * Added open source copyright license.
  41.  *
  42.  * Revision 1.39  1996/07/15 10:34:03  robertj
  43.  * Fixed uninitialised variable.
  44.  *
  45.  * Revision 1.38  1996/06/10 11:28:27  robertj
  46.  * Changes for better C++ compatibility.
  47.  *
  48.  * Revision 1.37  1996/04/30 12:33:48  robertj
  49.  * Changed "inPixels" boolean to enum for three coordinate systems.
  50.  *
  51.  * Revision 1.36  1995/10/14 15:06:56  robertj
  52.  * Fixed bug in changing fonts on status bar.
  53.  *
  54.  * Revision 1.35  1995/08/12 22:32:43  robertj
  55.  * Fixed setting of foreground/background colours with adjusted DrawBevelledRect().
  56.  *
  57.  * Revision 1.34  1995/07/31 12:13:01  robertj
  58.  * Added balloon help string to toolbar button codes.
  59.  *
  60.  * Revision 1.33  1995/06/04 12:38:24  robertj
  61.  * Redesign to add vertical tool bars and control wrapping.
  62.  *
  63.  * Revision 1.32  1995/04/25 11:28:13  robertj
  64.  * Fixed Borland compiler warnings.
  65.  *
  66.  * Revision 1.31  1995/04/03 11:21:31  robertj
  67.  * Fixed SetSectionText.
  68.  *
  69.  * Revision 1.30  1995/04/02 09:27:26  robertj
  70.  * Added "balloon" help.
  71.  *
  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.
  75.  *
  76.  * Revision 1.28  1995/02/19  04:19:19  robertj
  77.  * Added dynamically linked command processing.
  78.  *
  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.
  82.  *
  83.  * Revision 1.26  1995/01/18  09:04:23  robertj
  84.  * Added initialiser arrays for button bar and status bar.
  85.  *
  86.  * Revision 1.25  1995/01/15  04:53:08  robertj
  87.  * Fixed problems with stdarg and PString parameter on GNU compiler.
  88.  *
  89.  * Revision 1.24  1995/01/10  11:44:12  robertj
  90.  * Removed PString parameter in stdarg function for GNU C++ compatibility.
  91.  *
  92.  * Revision 1.23  1995/01/06  10:43:55  robertj
  93.  * Changed PRealFont usage from pointer to reference.
  94.  *
  95.  * Revision 1.22  1994/12/14  11:17:14  robertj
  96.  * Changed PDIMENSION to be unsigned causing untold number of changes.
  97.  *
  98.  * Revision 1.21  1994/11/28  23:30:21  robertj
  99.  * Added Update() call whenever a status bar section text is changed.
  100.  *
  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!
  104.  *
  105.  * Revision 1.20  1994/10/30  11:47:10  robertj
  106.  * Changed mechanism for doing notification callback functions.
  107.  *
  108.  * Revision 1.19  1994/08/21  23:43:02  robertj
  109.  * Changed parameter before variable argument list to NOT be a reference.
  110.  *
  111.  * Revision 1.18  1994/08/15  07:02:42  robertj
  112.  * Optimised status bar with transparent text display.
  113.  *
  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.
  116.  *
  117.  * Revision 1.16  1994/07/27  05:58:07  robertj
  118.  * Synchronisation.
  119.  *
  120.  * Revision 1.15  1994/06/25  11:55:15  robertj
  121.  * Unix version synchronisation.
  122.  *
  123.  * Revision 1.14  1994/04/20  12:17:44  robertj
  124.  * assert changes
  125.  *
  126.  * Revision 1.13  1994/04/01  14:00:00  robertj
  127.  * Fixed SetDimensions change bug
  128.  * ..
  129.  *
  130.  * Revision 1.12  1994/03/07  07:47:00  robertj
  131.  * Major upgrade
  132.  *
  133.  * Revision 1.11  1994/01/15  02:52:02  robertj
  134.  * Mac compatibilty changes (no nested classes).
  135.  *
  136.  * Revision 1.10  1994/01/13  03:36:48  robertj
  137.  * Created intermediate class PInteractorLayout for dialog-ish windows.
  138.  *
  139.  * Revision 1.9  1994/01/03  10:17:10  robertj
  140.  * Changed IsAncestor mechanism.
  141.  * ..
  142.  *
  143.  * Revision 1.8  1993/12/31  06:49:35  robertj
  144.  * Added PImgIcon class.
  145.  *
  146.  * Revision 1.7  1993/12/04  05:21:59  robertj
  147.  * Moved code from pwlib.inl
  148.  *
  149.  * Revision 1.6  1993/12/01  16:09:05  robertj
  150.  * Windows NT port.
  151.  *
  152.  * Revision 1.5  1993/11/20  17:26:28  robertj
  153.  * Change of button picture from PImage to PPixels
  154.  *
  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.
  157.  *
  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.
  161.  *
  162.  * Revision 1.2  1993/08/21  01:50:33  robertj
  163.  * Made Clone() function optional, default will assert if called.
  164.  *
  165.  * Revision 1.1  1993/08/21  01:07:35  robertj
  166.  * Initial revision
  167.  *
  168.  */
  169. #ifdef __GNUC__
  170. #pragma implementation "toolbars.h"
  171. #endif
  172. #include <pwlib.h>
  173. #include <pwclib/toolbars.h>
  174. #define new PNEW
  175. //////////////////////////////////////////////////////////////////////////////
  176. // PToolBar
  177. PToolBar::PToolBar(PInteractor * parent, BOOL vertical, BOOL autoWrap)
  178.   : PInteractorLayout(parent),
  179.     positionDown(vertical),
  180.     wrapControls(autoWrap)
  181. {
  182.   margin = owner->GetBorderSize()*3;
  183.   if (positionDown)
  184.     margin.SetHeight(margin.Height()*2);
  185.   else
  186.     margin.SetWidth(margin.Width()*2);
  187.   SetForegroundColour(owner->GetButtonFgColour());
  188.   SetBackgroundColour(owner->GetButtonBkColour());
  189. }
  190. void PToolBar::OnRedraw(PCanvas & canvas)
  191. {
  192.   canvas.SetMappingRect(canvas.GetViewportRect());
  193.   PRect bounds = canvas.GetDrawingBounds();
  194.   canvas.DrawBevelledRect(bounds, TRUE, FALSE);
  195. }
  196. PBalloon * PToolBar::OnBalloonHelp()
  197. {
  198.   return owner->DoBalloonHelp(NULL, 2);
  199. }
  200. void PToolBar::AddControl(PControl * control,
  201.                                     PDIMENSION gapSize, PDIMENSION elasticity)
  202. {
  203.   item.Append(new BarItem(PAssertNULL(control), gapSize, elasticity));
  204.   PDim myDim = GetDimensions(PixelCoords);
  205.   PDim ctlDim = control->GetDimensions(PixelCoords);
  206.   ctlDim += margin*2;
  207.   if (ctlDim.Width() > myDim.Width())
  208.     myDim.SetWidth(ctlDim.Width());
  209.   if (ctlDim.Height() > myDim.Height())
  210.     myDim.SetHeight(ctlDim.Height());
  211.   SetDimensions(myDim.Width(), myDim.Height(), PixelCoords);
  212. }
  213. void PToolBar::_SetDimensions(PDIMENSION width, PDIMENSION height,
  214.                               CoordinateSystem coords)
  215. {
  216.   PInteractorLayout::_SetDimensions(width, height, coords);
  217.   DoControlGeometry();
  218. }
  219. void PToolBar::DoControlGeometry()
  220. {
  221.   PDim myDim = GetDimensions(PixelCoords);
  222.   PDIMENSION barSize = positionDown ? myDim.Height() : myDim.Width();
  223.   PDIMENSION marginSize = positionDown ? margin.Height() : margin.Width();
  224.   PDIMENSION maxSize = 0;
  225.   PDIMENSION fixedSize = 0;
  226.   PDIMENSION propTotal = 0;
  227.   PINDEX i;
  228.   for (i = 0; i < item.GetSize(); i++) {
  229.     PDim ctlDim = item[i].control->GetDimensions(PixelCoords);
  230.     if (item[i].elasticity > 0)
  231.       propTotal += item[i].elasticity;
  232.     else
  233.       fixedSize += positionDown ? ctlDim.Height() : ctlDim.Width();
  234.     fixedSize += item[i].gapSize*marginSize;
  235.     if (positionDown) {
  236.       if (maxSize < ctlDim.Width())
  237.         maxSize = ctlDim.Width();
  238.     }
  239.     else {
  240.       if (maxSize < ctlDim.Height())
  241.         maxSize = ctlDim.Height();
  242.     }
  243.   }
  244.   PDIMENSION elasticUnit = 0;
  245.   if (propTotal > 0) {
  246.     elasticUnit = (barSize - fixedSize - marginSize*2)/propTotal;
  247.     if (elasticUnit < 10)
  248.       elasticUnit = 10;
  249.   }
  250.   PPoint ctlPos = margin;
  251.   for (i = 0; i < item.GetSize(); i++) {
  252.     PDim ctlDim = item[i].control->GetDimensions(PixelCoords);
  253.     if (item[i].elasticity > 0) {
  254.       if (positionDown)
  255.         ctlDim.SetHeight(item[i].elasticity*elasticUnit);
  256.       else
  257.         ctlDim.SetWidth(item[i].elasticity*elasticUnit);
  258.       item[i].control->SetDimensions(ctlDim, PixelCoords);
  259.     }
  260.     if (wrapControls) {
  261.       if (positionDown) {
  262.         if (ctlPos.Y() + ctlDim.Height() > myDim.Height()) {
  263.           ctlPos.SetX(maxSize + margin.Width());
  264.           ctlPos.SetY(margin.Height());
  265.         }
  266.       }
  267.       else {
  268.         if (ctlPos.X() + ctlDim.Width() > myDim.Width()) {
  269.           ctlPos.SetX(margin.Width());
  270.           ctlPos.SetY(maxSize + margin.Height());
  271.         }
  272.       }
  273.     }
  274.     item[i].control->SetPosition(ctlPos, TopLeftPixels, TopLeftPixels);
  275.     if (positionDown)
  276.       ctlPos.SetY(ctlPos.Y() + ctlDim.Height() + item[i].gapSize*marginSize);
  277.     else
  278.       ctlPos.SetX(ctlPos.X() + ctlDim.Width() + item[i].gapSize*marginSize);
  279.   }
  280. }
  281. //////////////////////////////////////////////////////////////////////////////
  282. // PButtonBar
  283. PButtonBar::PButtonBar(PInteractor *parent,
  284.              const ButtonID *IDs, PINDEX numIDs, BOOL vertical, BOOL autoWrap)
  285.   : PToolBar(parent, vertical, autoWrap)
  286. {
  287.   AddButtons(IDs, numIDs);
  288. }
  289. void PButtonBar::AddButtons(const ButtonID * IDs, PINDEX numIDs)
  290. {
  291.   // Calculate the maximum button size so far in bar.
  292.   PDIMENSION max_x = 0;
  293.   PDIMENSION max_y = 0;
  294.   PINDEX i;
  295.   for (i = 0; i < GetNumChildren(); i++) {
  296.     if (children[i].IsDescendant(PImageButton::Class())) {
  297.       PDim dim = children[i].GetDimensions(PixelCoords);
  298.       if (max_x < dim.Width())
  299.         max_x = dim.Width();
  300.       if (max_y < dim.Height())
  301.         max_y = dim.Height();
  302.     }
  303.   }
  304.   // Add in the new buttons, increasing the maximum size
  305.   for (i = 0; i < numIDs; i++) {
  306.     if (IDs[i].commandName != NULL || IDs[i].menuItem != 0) {
  307.       PRESOURCE_ID img1 = IDs[i].enabledImage;
  308.       if (img1 == 0)
  309.         img1 = IDs[i].menuItem;
  310.       PRESOURCE_ID img2 = IDs[i].disabledImage;
  311.       if (img2 == 0)
  312.         img2 = img1;
  313.       PPushButton * button;
  314.       if (img1 != 0)
  315.         button = new PImageButton(this, PImgIcon(img1), PImgIcon(img2));
  316.       else
  317.         button = new PImageButton(this);
  318.       button->SetControlID(IDs[i].menuItem);
  319.       if (IDs[i].commandName != NULL)
  320.         button->SetNotifier(PCREATE_COMMAND(IDs[i].commandName), TRUE);
  321.       PRESOURCE_ID help = IDs[i].balloonHelp;
  322.       if (help == 0)
  323.         help = IDs[i].menuItem;
  324.       if (help != 0) {
  325.         PResourceString str(help);
  326.         button->SetBalloonHelp(str);
  327.       }
  328.       button->Show();
  329.       PDim dim = button->GetDimensions(PixelCoords);
  330.       if (max_x < dim.Width())
  331.         max_x = dim.Width();
  332.       if (max_y < dim.Height())
  333.         max_y = dim.Height();
  334.     }
  335.   }
  336.   for (i = 0; i < numIDs; i++) {
  337.     if (IDs[i].commandName != NULL || IDs[i].menuItem != 0) {
  338.       PControl * button = GetControl(IDs[i].menuItem);
  339.       PAssertNULL(button)->SetDimensions(max_x, max_y, PixelCoords);
  340.       int gaps = 1;
  341.       while (i+gaps < numIDs &&
  342.                 (IDs[i+gaps].commandName == NULL && IDs[i+gaps].menuItem == 0))
  343.         gaps++;
  344.       AddControl(button, gaps-1);
  345.     }
  346.   }
  347. }
  348. void PButtonBar::OnControlNotify(PControl & control, int code)
  349. {
  350.   PInteractorLayout::OnControlNotify(control, code);
  351.   if (control.GetNotifier().IsNULL()) {
  352.     PInteractor * p = parent;
  353.     while (p->GetParent() != NULL)
  354.       p = p->GetParent();
  355.     PTopLevelWindow * mainWindow = (PTopLevelWindow *)p;
  356.     mainWindow->OnMenuStartSelect();
  357.     PRootMenu * menu = mainWindow->GetMenu();
  358.     if (menu != NULL) {
  359.       PMenuItem * item = menu->GetItemFromKey(control.GetControlID());
  360.       if (item != NULL && item->IsEnabled())
  361.         mainWindow->OnMenuItemSelect(*item);
  362.     }
  363.   }
  364. }
  365. //////////////////////////////////////////////////////////////////////////////
  366. // PStatusBar
  367. PStatusBar::PStatusBar(PInteractor * parent, PINDEX numSections)
  368.   : PToolBar(parent)
  369. {
  370.   PDIMENSION width =
  371.        parent->GetDimensions(PixelCoords).Width()/numSections - margin.Width();
  372.   PDIMENSION height = font.GetHeight(TRUE) + margin.Height();
  373.   for (PINDEX i = 0; i < numSections; i++) {
  374.     Section * s = new Section(this);
  375.     s->SetDimensions(width, height, PixelCoords);
  376.     AddControl(s, i < numSections-1, 1);
  377.   }
  378. }
  379. void PStatusBar::SetFont(const PFont & newFont, BOOL toChildren)
  380. {
  381.   PToolBar::SetFont(newFont, toChildren);
  382.   PDIMENSION height = font.GetHeight(TRUE) + margin.Height();
  383.   for (PINDEX i = 0; i < item.GetSize(); i++)
  384.     item[i].control->SetDimensions(1, height, PixelCoords);
  385.   DoControlGeometry();
  386.   height += margin.Height()*2;
  387.   SetDimensions(GetDimensions(ScreenCoords).Width(), height, PixelCoords);
  388. }
  389. void PStatusBar::SetText(const PString & str)
  390. {
  391.   SetSectionText(0, str);
  392. }
  393. void PStatusBar::SetText(PRESOURCE_ID resId, ...)
  394. {
  395.   va_list args;
  396.   va_start(args, resId);
  397.   PString str;
  398.   PResourceString fmt(resId);
  399.   str.vsprintf(fmt, args);
  400.   SetSectionText(0, str);
  401. }
  402. void PStatusBar::SetText(const char * fmt, ...)
  403. {
  404.   va_list args;
  405.   va_start(args, fmt);
  406.   PString str;
  407.   str.vsprintf(fmt, args);
  408.   SetSectionText(0, str);
  409. }
  410. void PStatusBar::SetSectionText(PINDEX section, const PString & str)
  411. {
  412.   Section & s = GetSection(section);
  413.   if (s.GetName() != str) {
  414.     s.SetName(str);
  415.     s.Update();
  416.   }
  417. }
  418. void PStatusBar::SetSectionText(PINDEX section, PRESOURCE_ID resId, ...)
  419. {
  420.   va_list args;
  421.   va_start(args, resId);
  422.   PResourceString fmt(resId);
  423.   SetSectionText(section, pvsprintf(fmt, args));
  424. }
  425. void PStatusBar::SetSectionText(PINDEX section, const char * fmt, ...)
  426. {
  427.   va_list args;
  428.   va_start(args, fmt);
  429.   SetSectionText(section, pvsprintf(fmt, args));
  430. }
  431. void PStatusBar::SetSectionAlignment(PINDEX section,
  432.                                               PCanvas::DrawStringOptions align)
  433. {
  434.   GetSection(section).SetAlignment(align);
  435. }
  436. void PStatusBar::SetSectionWidth(PINDEX section, const PString & longestString)
  437. {
  438.   SetSectionWidth(section,
  439.                        PDrawCanvas(this).MeasureString(longestString).Width());
  440. }
  441. void PStatusBar::SetSectionWidth(PINDEX section,
  442.                                   const PRESOURCE_ID * strIDs, PINDEX nStrings)
  443. {
  444.   PDrawCanvas canvas(this);
  445.   PDIMENSION max = 0;
  446.   for (PINDEX i = 0; i < nStrings; i++) {
  447.     PDIMENSION width=canvas.MeasureString(PResourceString(strIDs[i])).Width();
  448.     if (max < width)
  449.       max = width;
  450.   }
  451.   SetSectionWidth(section, max);
  452. }
  453. void PStatusBar::SetSectionWidth(PINDEX section, int width)
  454. {
  455.   Section & s = GetSection(section);
  456.   if (width > 0)
  457.     s.SetDimensions(width, s.GetDimensions(LocalCoords).Height(), LocalCoords);
  458.   item[section].elasticity = width < 0 ? -width : 0;
  459.   SetDimensions(GetDimensions(LocalCoords), LocalCoords);
  460. }
  461. PStatusBar::Section & PStatusBar::GetSection(PINDEX section) const
  462. {
  463.   PInteractor & s = *item[section].control;
  464.   PAssert(s.IsDescendant(Section::Class()), PInvalidParameter);
  465.   return (Section &)s;
  466. }
  467. PStatusBar::Section::Section(PInteractor * parent)
  468.   : PStaticText(parent)
  469. {
  470.   SetBackgroundColour(owner->GetButtonBkColour());
  471.   Show();
  472. }
  473. void PStatusBar::Section::OnRedraw(PCanvas & canvas)
  474. {
  475.   canvas.SetMappingRect(canvas.GetViewportRect());
  476.   PRect bounds = canvas.GetDrawingBounds();
  477.   canvas.DrawBevelledRect(bounds, FALSE, FALSE);
  478.   bounds.Inflate(-1, -1);
  479.   canvas.SetTextFgColour(owner->GetButtonFgColour());
  480.   canvas.SetTextBkColour(PColour(0,0,0,0));
  481.   canvas.DrawString(bounds, GetName(), alignment);
  482. }
  483. // End Of File ///////////////////////////////////////////////////////////////