home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 September / Chip_2001-09_cd1.bin / zkuste / delphi / kolekce / d12345 / CHEMPLOT.ZIP / TPlot / Plottoolbar.pas < prev    next >
Pascal/Delphi Source File  |  2001-05-30  |  17KB  |  533 lines

  1. unit Plottoolbar;
  2.  
  3. {$I Plot.inc}
  4.  
  5. {-----------------------------------------------------------------------------
  6. The contents of this file are subject to the Q Public License
  7. ("QPL"); you may not use this file except in compliance
  8. with the QPL. You may obtain a copy of the QPL from 
  9. the file QPL.html in this distribution, derived from:
  10.  
  11. http://www.trolltech.com/products/download/freelicense/license.html
  12.  
  13. The QPL prohibits development of proprietary software. 
  14. There is a Professional Version of this software available for this. 
  15. Contact sales@chemware.hypermart.net for more information.
  16.  
  17. Software distributed under the QPL is distributed on an "AS IS" basis,
  18. WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the QPL for
  19. the specific language governing rights and limitations under the QPL.
  20.  
  21. The Original Code is: Plottoolbar.pas, released 12 May 2001.
  22.  
  23. The Initial Developer of the Original Code is Mat Ballard.
  24. Portions created by Mat Ballard are Copyright (C) 1999 Mat Ballard.
  25. Portions created by Microsoft are Copyright (C) 1998, 1999 Microsoft Corp.
  26. All Rights Reserved.
  27.  
  28. Contributor(s): Mat Ballard                 e-mail: mat.ballard@chemware.hypermart.net.
  29.  
  30. Last Modified: 03/25/2001
  31. Current Version: 2.00
  32.  
  33. You may retrieve the latest version of this file from:
  34.  
  35.         http://Chemware.hypermart.net/
  36.  
  37. This work was created with the Project JEDI VCL guidelines:
  38.  
  39.         http://www.delphi-jedi.org/Jedi:VCLVCL
  40.  
  41. in mind. 
  42.  
  43. Purpose:
  44. An additional user interface for TPlot.
  45.  
  46.  
  47. Known Issues: Does not work when component is added from the IDE.
  48.               exception EClassNotFound: class TToolBar not found".
  49.               even adding a NoButtons property, and modifying CreateToolButtons,
  50.               so that 54 buttons DO exist, does not work. 
  51.  
  52. -----------------------------------------------------------------------------}
  53. interface
  54.  
  55. uses
  56.   Classes, SysUtils,
  57. {$IFDEF WINDOWS}
  58.   WinTypes, WinProcs,
  59.   ComCtrls, Controls,
  60. {$ENDIF}
  61. {$IFDEF WIN32}
  62.   Windows,
  63.   ComCtrls, Controls, Dialogs,
  64. {$ENDIF}
  65. {$IFDEF LINUX}
  66.   QComCtrls, QControls, 
  67. {$ENDIF}
  68.  
  69.   Plotdefs, Plot, Misc, Plottooledit;
  70.  
  71. type
  72.   TPlotToolBar = class(TToolBar)
  73.   private
  74.     FCanConfigure: Boolean;
  75.     //FNoButtons: Integer;
  76.     FPlot: TPlot;
  77.  
  78.     function ToolButtonExists(ATag: Integer; ACaption: String): Boolean;
  79.   protected
  80.     function GetPlot(Target: TObject): TPlot; virtual;
  81. {GetPlot is part of the Notification mechanism for linking components.}
  82.     procedure SetPlot(Value: TPlot);
  83. {This sets the Plot, and so creates the buttons.}
  84.     {function GetNoButtons: Integer;
  85.     procedure SetNoButtons(Value: Integer);}
  86. {This creates the buttons.}
  87.     procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  88. {Notification is part of the Notification mechanism for linking components.}
  89.     procedure CreateToolButtons;
  90. {This creates all the ToolButtons. It bascially "steals" them from the
  91.  TPlot.PlotPopupMenu.}
  92.     procedure DidMouseDown(Sender: TObject; Button: TMouseButton;
  93.       Shift: TShiftState; X, Y: Integer);
  94. {This is the target OnClick method of all the ToolButtons.
  95.  It calls the MouseDown for a right click.}
  96.     procedure MouseDown(Button: TMouseButton;
  97.       Shift: TShiftState; X, Y: Integer); override;
  98. {This calls the ancestor for a left click, or runs the ToolEditor for a right click.}
  99.   public
  100.     constructor Create(AOwner: TComponent); override;
  101. {The standard constructor, in which the ToolButtonOptions are created and other
  102.  properties set.}
  103.     destructor Destroy; override;
  104. {The standard destructor, in which the ToolButtonOptions are freed.}
  105.     procedure ApplyChanges(Sender: TObject);
  106. {This applies any changes (to ToolButton visibility) from the ToolEditor to this
  107.  component.}
  108.     procedure ApplyOptions(Value: TPopupOptions);
  109. {This applies any changes (to ToolButton visibility) from TPlot to this
  110.  component.}
  111.  
  112.     {procedure ShowArrangement;}
  113. {This (leads to) the display of the ToolEditor as a design-time property editor.}
  114.   published
  115.     {property Arrangement: string read FArrangement write FArrangement {$IFDEF DELPHI2_UP . stored False .$ENDIF}
  116. {This is used to invoke the ToolEditor as a design-time property editor.
  117.  See ShowArrangement.}
  118.     property CanConfigure: Boolean read FCanConfigure write FCanConfigure;
  119. {Can the user configure the ToolBar ?}
  120.     //property NoButtons: Integer read GetNoButtons write SetNoButtons;
  121.  
  122.     property Plot: TPlot read FPlot write SetPlot;
  123. {This is the Plot to which this ToolBar is connected.}
  124. end;
  125.  
  126. implementation
  127.  
  128. constructor TPlotToolBar.Create(AOwner: TComponent);
  129. begin
  130.   inherited Create(AOwner);
  131.   FPlot := nil;
  132.   ShowHint := TRUE;
  133.   AutoSize := TRUE;
  134.   FCanConfigure := TRUE;
  135. end;
  136.  
  137. destructor TPlotToolBar.Destroy;
  138. begin
  139.   inherited Destroy;
  140. end;
  141.  
  142. {------------------------------------------------------------------------------
  143.     Procedure: TPlotToolBar.ShowArrangement;
  144.   Description: Property editor methods, et cetera
  145.        Author: Mat Ballard
  146.  Date created: 04/20/2001
  147. Date modified: 05/02/2001 by Mat Ballard
  148.       Purpose: design-time user interface
  149.  Known Issues:
  150.  ------------------------------------------------------------------------------}
  151. {procedure TPlotToolBar.ShowArrangement;
  152. begin
  153.   Self.MouseDown(mbRight, [ssRight], 1, 1);
  154. end;}
  155.  
  156. { Check target object is a Plot }
  157. function TPlotToolBar.GetPlot(Target: TObject): TPlot;
  158. begin
  159.   Result := Target as TPlot;
  160. end;
  161.  
  162. { Set the Plot component to affect }
  163. procedure TPlotToolBar.SetPlot(Value: TPlot);
  164. begin
  165.   if (csDesigning in ComponentState) then
  166.   begin
  167.     ShowMessage('My apologies - you cannot set the Plot in the IDE' + #10+#10 +
  168.       'Please set it in the FormCreate event instead.');
  169.     exit;
  170.   end;
  171.  
  172.   if Value <> FPlot then
  173.   begin
  174.     if (Value = nil) then
  175.     begin
  176.       FPlot := Value;
  177.       FPlot.SetPlotToolBar(TToolBar(nil));
  178.     end
  179.     else
  180.     begin
  181.       FPlot := Value;
  182. {$IFDEF DELPHI1}
  183.       Value.Notification(Self, opInsert); {???}
  184. {$ELSE}
  185.       Value.FreeNotification(Self);
  186. {$ENDIF}
  187.       CreateToolButtons;
  188.       FPlot.SetPlotToolBar(TToolBar(Self));
  189.     end;
  190.   end;
  191. end;
  192.  
  193. { Note deletion of attached Plot component }
  194. procedure TPlotToolBar.Notification(AComponent: TComponent;
  195.   Operation: TOperation);
  196. begin
  197.   inherited Notification(AComponent, Operation);
  198.   if (Operation = opRemove) and (AComponent = Plot) then
  199.     FPlot := nil;
  200. end;
  201.  
  202. {function TPlotToolBar.GetNoButtons: Integer;
  203. begin
  204.   GetNoButtons := Self.ButtonCount;
  205. end;}
  206.  
  207. {------------------------------------------------------------------------------
  208.     Procedure: TPlotToolBar.SetNoButtons
  209.   Description: This creates the buttons
  210.        Author: Mat Ballard
  211.  Date created: 11/18/2000
  212. Date modified: 11/18/2000 by Mat Ballard
  213.       Purpose: modularize user-interface code
  214.  Known Issues:
  215.  ------------------------------------------------------------------------------}
  216. {procedure TPlotToolBar.SetNoButtons(Value: Integer);
  217. var
  218.   i: Integer;
  219.   TempToolButton: TToolButton;
  220. begin
  221.   if ((Self.ButtonCount = 0) and
  222.       (Value > 10)) then
  223.   begin
  224.     for i := 0 to Value-1 do
  225.     begin
  226.       TempToolButton := TToolButton.Create(Self);
  227. {add the TempToolButton:
  228.       TempToolButton.Parent := Self;
  229.     end;
  230.   end;
  231. end;}
  232.  
  233. {------------------------------------------------------------------------------
  234.     Procedure: TPlotToolBar.CreateToolButtons
  235.   Description: creates tool buttons
  236.        Author: Mat Ballard
  237.  Date created: 11/18/2000
  238. Date modified: 11/18/2000 by Mat Ballard
  239.       Purpose: modularize user-interface code
  240.  Known Issues:
  241.  ------------------------------------------------------------------------------}
  242. procedure TPlotToolBar.CreateToolButtons;
  243. var
  244.   i, j: Word;
  245.   TempToolButton: TToolButton;
  246.   TheName: String;
  247. {$IFDEF COMPILER35}
  248.   Index: Integer;
  249. {$ENDIF}  
  250. begin
  251. {don't create ToolButtons when the Plot property is streamed in:}
  252.   if (csLoading in ComponentState) then exit;
  253.   if (FPlot = nil) then exit;
  254.  
  255. {who needs more than 32 menus ?!}
  256.   if (FPlot.PlotPopupMenu.Items.Count > 32) then raise
  257.     EComponentError.CreateFmt('TPlotToolBar.CreateToolButtons: I cannot handle more than %d Sub-menus !',
  258.       [FPlot.PlotPopupMenu.Items.Count]);
  259.  
  260. {Create the main ToolButtons, which correspond to each sub-menu,
  261.  then the menu items within each submenu.
  262.  Note the bizzare order required by Windows}
  263. {$IFDEF MSWINDOWS}
  264.   for i := FPlot.PlotPopupMenu.Items.Count-1 downto 0 do
  265.   begin
  266.     for j := FPlot.PlotPopupMenu.Items[i].Count-1 downto 0 do
  267. {$ENDIF}
  268. {$IFDEF LINUX}
  269.   for i := 0 to FPlot.PlotPopupMenu.Items.Count-1 do
  270.   begin
  271.     for j := 0 to FPlot.PlotPopupMenu.Items[i].Count-1 do
  272. {$ENDIF}
  273.     begin
  274.       if (FPlot.PlotPopupMenu.Items[i].Items[j].Caption <> '-') then
  275.       begin
  276.         if (not ToolButtonExists(
  277.            FPlot.PlotPopupMenu.Items[i].Items[j].Tag,
  278.            FPlot.PlotPopupMenu.Items[i].Items[j].Caption)) then
  279.         begin
  280.           TempToolButton := TToolButton.Create(Self);
  281.           TempToolButton.Caption := FPlot.PlotPopupMenu.Items[i].Items[j].Caption;
  282.           TheName := CleanString(TempToolButton.Caption, '&');
  283.           TheName := CleanString(TheName, ' ');
  284.           TheName := CleanString(TheName, '.');
  285.           TheName := CleanString(TheName, '!');
  286.           TheName := CleanString(TheName, ':');
  287.           TheName := CleanString(TheName, '0');
  288.           TempToolButton.Name := TheName;
  289.           TempToolButton.Style := tbsButton;
  290.           TempToolButton.Tag := FPlot.PlotPopupMenu.Items[i].Items[j].Tag;
  291.           TempToolButton.Hint := TheName + ' - ' + FPlot.PlotPopupMenu.Items[i].Items[j].Hint;
  292. {$IFDEF COMPILER4_UP}
  293.           TempToolButton.ImageIndex := FPlot.PlotPopupMenu.Items[i].Items[j].ImageIndex;
  294. {$ENDIF}
  295.           TempToolButton.OnClick := FPlot.PlotPopupMenu.Items[i].Items[j].OnClick;
  296. {When the ToolButton is right-clicked, DidMouseDown calls MouseDown, which fires up the ToolEditor.}
  297.           TempToolButton.OnMouseDown := DidMouseDown;
  298. {add the TempToolButton:}
  299.           TempToolButton.Parent := Self;
  300.           {TempToolButton.Visible := TRUE;
  301.           TempToolButton.Enabled := TRUE;}
  302.         end;
  303.       end;
  304.     end; {j over menu items}
  305.     if (i <> 0) then
  306.     begin
  307.       TempToolButton := TToolButton.Create(Self);
  308.       TempToolButton.Style := tbsSeparator;
  309.       //TempToolButton.Wrap := TRUE;
  310.       TempToolButton.Width := 8;
  311.       TempToolButton.Height := 8;
  312. {add the seperator TempToolButton:}
  313.       TempToolButton.Parent := Self;
  314.     end
  315.   end; {i over submenus}
  316. {$IFDEF COMPILER35}
  317.   Index := 0;
  318.   for i := 0 to Self.ButtonCount-1 do
  319.   begin
  320.     if (Self.Buttons[i].Style = tbsButton) then
  321.     begin
  322.       Self.Buttons[i].ImageIndex := Index;
  323.       Inc(Index);
  324.     end;
  325.   end;
  326. {$ENDIF}
  327. end;
  328.  
  329. {------------------------------------------------------------------------------
  330.      Function: TPlotToolBar.ToolButtonExists
  331.   Description: Does this ToolButton exist ? Based on Tag and Caption
  332.        Author: Mat Ballard
  333.  Date created: 04/25/2000
  334. Date modified: 04/25/2000 by Mat Ballard
  335.       Purpose: do we need to add a ToolButton item ?
  336.  Return Value: Boolean;
  337.  Known Issues:
  338.  ------------------------------------------------------------------------------}
  339. function TPlotToolBar.ToolButtonExists(ATag: Integer; ACaption: String): Boolean;
  340. var
  341.   i: Integer;
  342. begin
  343. {$IFDEF MSWINDOWS}
  344.   for i := 0 to Self.ButtonCount-1 do
  345.   begin
  346.     if ((Self.Buttons[i].Tag = ATag) and
  347.         (TToolButton(Self.Buttons[i]).Caption = ACaption)) then
  348. {$ENDIF}
  349. {$IFDEF LINUX}
  350.   for i := 0 to Self.ControlCount-1 do
  351.   begin
  352.     if ((Self.Controls[i].Tag = ATag) and
  353.         (TToolButton(Self.Controls[i]).Caption = ACaption)) then
  354. {$ENDIF}
  355.     begin
  356.       ToolButtonExists := TRUE;
  357.       exit;
  358.     end;
  359.   end;
  360.   ToolButtonExists := FALSE;
  361. end;
  362.  
  363. procedure TPlotToolBar.DidMouseDown(Sender: TObject; Button: TMouseButton;
  364.   Shift: TShiftState; X, Y: Integer);
  365. begin
  366.   if (Button = mbRight) then
  367.     MouseDown(Button, Shift, X, Y);
  368. end;
  369.  
  370. procedure TPlotToolBar.MouseDown(Button: TMouseButton;
  371.   Shift: TShiftState; X, Y: Integer);
  372. var
  373.   ToolBarEditForm: TToolBarEditForm;
  374. begin
  375.   if ((Button = mbRight) and (FCanConfigure)) then
  376.   begin
  377.     ToolBarEditForm := TToolBarEditForm.Create(nil);
  378.     ToolBarEditForm.SetupButtons(TToolBar(Self));
  379.     ToolBarEditForm.ShowModal;
  380.     ToolBarEditForm.Free;
  381.   end
  382.   else
  383.     inherited MouseDown(Button, Shift, X, Y);
  384. end;
  385.  
  386. procedure TPlotToolBar.ApplyChanges(Sender: TObject);
  387. var
  388.   i: Integer;
  389. {$IFDEF LINUX}
  390.   j,
  391.   TargetIndex,
  392.   TheTag: Integer;
  393. {$ENDIF}
  394. begin
  395.   for i := 0 to Self.ButtonCount-1 do
  396.   begin
  397. {$IFDEF MSWINDOWS}
  398.     Self.Buttons[i].Visible :=
  399.       TToolBar(Sender).Buttons[i].Visible;
  400. {$ENDIF}
  401. {$IFDEF LINUX}
  402.     TargetIndex := -1;
  403.     TheTag := TToolButton(TToolBar(Sender).Controls[i]).Tag;
  404.     for j := 0 to Self.ButtonCount-1 do
  405.     begin
  406.       if (TToolButton(Self.Controls[j]).Tag = TheTag) then
  407.       begin
  408.         TargetIndex := j;
  409.         break;
  410.       end;
  411.     end;
  412.     Self.Controls[TargetIndex].Visible :=
  413.       TToolBar(Sender).Controls[i].Visible;
  414. {$ENDIF}
  415.   end;
  416.   {  for i := 0 to Ord(High(TMainMenus)) do
  417.     FPlotPopUpMenu.Items[i].Visible :=
  418.       FPlotPopUpMenu.Items[i].Visible and
  419.         (TMainMenus(i) in FOptions.Menu);}
  420. end;
  421.  
  422. procedure TPlotToolBar.ApplyOptions(Value: TPopupOptions);
  423. var
  424.   i, j, Index: Integer;
  425. begin
  426.   if (FPlot = nil) then exit;
  427.  
  428.   for Index := 0 to Self.ButtonCount-1 do
  429.   begin
  430. {$IFDEF MSWINDOWS}
  431.     if (FPlot.GetIndicesFromTag(Self.Buttons[Index].Tag, i, j)) then
  432.     begin
  433.       case i of
  434.         Ord(mnuFile): Self.Buttons[Index].Visible :=
  435.           (TFileMenus(j) in Value.File_);
  436.         Ord(mnuEdit): Self.Buttons[Index].Visible :=
  437.           (TEditMenus(j) in Value.Edit);
  438.         Ord(mnuView): Self.Buttons[Index].Visible :=
  439.           (TViewMenus(j) in Value.View);
  440.         Ord(mnuCalc): Self.Buttons[Index].Visible :=
  441.           (TCalcMenus(j) in Value.Calc);
  442.       end; {case}
  443.     end; {GetIndicesFromTag}
  444. {$ENDIF}
  445. {$IFDEF LINUX}
  446.     if (FPlot.GetIndicesFromTag(Self.Controls[Index].Tag, i, j)) then
  447.     begin
  448.       case i of
  449.         Ord(mnuFile): Self.Controls[Index].Visible :=
  450.           (TFileMenus(j) in Value.File_);
  451.         Ord(mnuEdit): Self.Controls[Index].Visible :=
  452.           (TEditMenus(j) in Value.Edit);
  453.         Ord(mnuView): Self.Controls[Index].Visible :=
  454.           (TViewMenus(j) in Value.View);
  455.         Ord(mnuCalc): Self.Controls[Index].Visible :=
  456.           (TCalcMenus(j) in Value.Calc);
  457.       end; {case}
  458.     end; {GetIndicesFromTag}
  459. {$ENDIF}
  460.   end; {for Index}
  461. end;
  462.  
  463. {procedure TPlotToolBar.CreateToolButtons;
  464. var
  465.   i, j: Word;
  466.   TempToolButton: TToolButton;
  467.   TheName: String;
  468.   Index: Integer;
  469. begin
  470.   if (csLoading in ComponentState) then exit;
  471.   if (FPlot = nil) then exit;
  472.  
  473. {who needs more than 32 menus ?!
  474.   if (FPlot.PlotPopupMenu.Items.Count > 32) then raise
  475.     EComponentError.CreateFmt('TPlotToolBar.CreateToolButtons: I cannot handle more than %d Sub-menus !',
  476.       [FPlot.PlotPopupMenu.Items.Count]);
  477.  
  478. {Create the main ToolButtons, which correspond to each sub-menu,
  479.  then the menu items within each submenu.
  480.  Note the bizzare order required by Windows
  481.   Index := 0;
  482.   for i := 0 to FPlot.PlotPopupMenu.Items.Count-1 do
  483.   begin
  484.     for j := 0 to FPlot.PlotPopupMenu.Items[i].Count-1 do
  485.     begin
  486.       if (FPlot.PlotPopupMenu.Items[i].Items[j].Caption <> '-') then
  487.         Inc(Index);
  488.     end;
  489. {add the seperator TempToolButton:
  490.     if (i <> 0) then
  491.       Inc(Index);
  492.   end;
  493.  
  494.   SetNoButtons(Index);
  495.  
  496.   Index := 0;
  497.   for i := 0 to FPlot.PlotPopupMenu.Items.Count-1 do
  498.   begin
  499.     for j := 0 to FPlot.PlotPopupMenu.Items[i].Count-1 do
  500.     begin
  501.       if (FPlot.PlotPopupMenu.Items[i].Items[j].Caption <> '-') then
  502.       begin
  503.         Self.Buttons[Index].Caption := FPlot.PlotPopupMenu.Items[i].Items[j].Caption;
  504.         TheName := CleanString(Self.Buttons[Index].Caption, '&');
  505.         TheName := CleanString(TheName, ' ');
  506.         TheName := CleanString(TheName, '.');
  507.         TheName := CleanString(TheName, '!');
  508.         Self.Buttons[Index].Name := TheName;
  509.         Self.Buttons[Index].Style := tbsButton;
  510.         Self.Buttons[Index].Tag := FPlot.PlotPopupMenu.Items[i].Items[j].Tag;
  511.         Self.Buttons[Index].Hint := TheName + ' - ' + FPlot.PlotPopupMenu.Items[i].Items[j].Hint;
  512. {.$ IFDEF COMPILER35_UP
  513.         Self.Buttons[Index].ImageIndex := Index;
  514. {.$ ENDIF
  515.         Self.Buttons[Index].OnClick := FPlot.PlotPopupMenu.Items[i].Items[j].OnClick;
  516. {When the ToolButton is right-clicked, DidMouseDown calls MouseDown, which fires up the ToolEditor.
  517.         Self.Buttons[Index].OnMouseDown := DidMouseDown;
  518.         Inc(Index);
  519.       end;
  520.     end; {j over menu items
  521.     {if (i <> 0) then
  522.     begin
  523.       Self.Buttons[Index].Style := tbsSeparator;
  524.       Self.Buttons[Index].Width := 8;
  525.       Self.Buttons[Index].Height := 8;
  526.       Inc(Index);
  527.     end
  528.   end; {i over submenus
  529. end;}
  530.  
  531.  
  532. end.
  533.