ACSHelper.pas
上传用户:yj_qiu
上传日期:2022-08-08
资源大小:23636k
文件大小:16k
源码类别:

游戏引擎

开发平台:

Delphi

  1. (*
  2.  @Abstract(GUI helper unit)
  3.  (C) 2006 George "Mirage" Bakhtadze. <a href="http://www.casteng.com">www.casteng.com</a> <br>
  4.  Unit contains helper classes for GUI applications <br>
  5.  Supported controls (including all descendants): TTextGUIItem , TSwitchButton, TCheckBox, TTrackBar
  6. *)
  7. {$Include C2Defines.inc}
  8. unit ACSHelper;
  9. interface
  10. uses
  11.   TextFile,
  12.   SysUtils, 
  13.   Basics, BaseClasses, GUIHelper, BaseMsg, GUIMsg, ItemMsg, Props, ACSBase, ACS, ACSAdv;
  14. const
  15.   TotalImmediateApplyControls = 5;                                                      // ToDo: Move out of here
  16.   ImmediateApplyControls: array[0..TotalImmediateApplyControls-1] of string =
  17.    ('Gamma', 'Contrast', 'Brightness', 'SoundVolume', 'MusicVolume');
  18.   TotalNotifyingApplyControls = 1;
  19.   NotifyingApplyControls: array[0..TotalNotifyingApplyControls-1] of string =
  20.    ('UserName');
  21.   FormNamesCapacityStep = 1;
  22.   // On click predefined actions
  23.   TotalActions = 9;
  24.   aShow = 0; aShowSolely = 1; aToggle = 2; aClose = 3; aOK = 4; aApply = 5; aCancel = 6; aReset = 7; aBack = 8;
  25.   ActionStr: array[0..TotalActions-1] of string = ('Show', 'Invoke', 'Toggle', 'Close', 'OK', 'Apply', 'Cancel', 'Reset', 'Back');
  26. type
  27.   TGUIState = record
  28.     Visibility: array of Boolean;
  29.   end;
  30.   TACSHelper = class(TGUIHelper)
  31.   private
  32.     Config: TProperties;
  33.     Items: TItemsManager;
  34.     GUIRoot: TGUIRootItem;
  35.     TotalFormNames: Integer;
  36.     FormNames: array of string;
  37.     TotalHistory: Integer;
  38.     History: array of TGUIState;
  39.     procedure Initialize;
  40.     function GetCommand(const s: string; var Argument: string): Integer;
  41.     function FindForm(const s: string): TItem;
  42.   protected
  43.     procedure ControlToConfig(const FormName, OptionName: string; AConfig: TProperties); override;
  44.     procedure ConfigToControl(const FormName, OptionName: string; AConfig: TProperties); override;
  45.   public
  46.     GUIState: Integer;
  47.     constructor Create(AItems: TItemsManager; AConfig: TProperties);
  48.     destructor Destroy; override;
  49.     procedure HandleMessage(const Msg: TMessage); override;
  50.     procedure HandleGUIClick(const Item: TGUIItem);
  51. // Items manipulation
  52.     procedure HideAllForms; virtual;
  53.     function ControlExists(const Name: string): Boolean; override;
  54.     function IsControlVisible(const Name: string; CheckHierarchy: Boolean): Boolean; override;
  55.     procedure ShowControl(const Name: string); override;
  56.     procedure HideControl(const Name: string); override;
  57.     procedure ToggleControl(const Name: string); override;                    // Toggles item's visibility
  58.     procedure EnableControl(const Name: string); override;
  59.     procedure DisableControl(const Name: string); override;
  60.     procedure SetControlText(const Name, Text: string); override;
  61.     function GetControlText(const Name: string): string; override;
  62.     function GetControlFormName(const Name: string): string; override;
  63. // Properties filling
  64.     function GUIToString(Item: TItem): string; virtual;
  65.     procedure ResetConfig(const FormName: string; ADefaultConfig: TProperties); override;
  66. // Form navigation
  67.     procedure AddForm(const FormName: string);
  68.     procedure LoadForms(const FileName: string);
  69.     procedure ShowForm(const FormName: string; Solely: Boolean);
  70.     procedure RememberState;
  71.     procedure ShowPreviousState;
  72.     function IsWithinGUI(AX, AY: Single): Boolean;
  73.   end;
  74. implementation
  75. { TACSHelper }
  76. procedure TACSHelper.Initialize;
  77. var Temp: TItems;
  78. begin
  79.   if Items.Root.ExtractByClass(TGUIRootItem, Temp) > 1 then begin
  80.     {$IFDEF LOGGING} Log.Log(ClassName + '.Create: More than one items of class TGUIRootItem found', lkWarning); {$ENDIF}
  81.   end;
  82.   if Temp = nil then begin
  83.     {$IFDEF LOGGING} Log.Log(ClassName + '.Create: No items of class TGUIRootItem found', lkError); {$ENDIF}
  84.     Exit;
  85.   end;
  86.   GUIRoot := Temp[0] as TGUIRootItem;
  87.   Temp := nil;
  88. end;
  89. function TACSHelper.GetCommand(const s: string; var Argument: string): Integer;
  90. var i, t: Integer;
  91. begin
  92.   Result := -1;
  93.   for i := 0 to TotalActions-1 do begin
  94.     t := Pos(UpperCase(ActionStr[i]), UpperCase(s));
  95.     if (t > 0) and (t = Length(s) - Length(ActionStr[i]) + 1) then begin
  96.       Argument := Copy(s, 1, t-1);
  97.       Result := i;
  98.       Exit;
  99.     end;
  100.   end;
  101. end;
  102. function TACSHelper.FindForm(const s: string): TItem;
  103. var i: Integer;
  104. begin
  105.   Result := nil;
  106.   for i := 0 to TotalFormNames-1 do if FormNames[i] = s then begin
  107.     Result := GUIRoot.GetChildByName(s, True);
  108.     Exit;
  109.   end;
  110. end;
  111. procedure TACSHelper.ControlToConfig(const FormName, OptionName: string; AConfig: TProperties);
  112. var i: Integer; Form, Item: TItem;
  113. begin
  114.   Form := GUIRoot.GetChildByName(FormName, True);
  115.   if not (Form is TGUIItem) then Exit;
  116.   Item := Form.GetChildByName(OptionName, True);
  117.   if Item = nil then Exit;
  118.   for i := 0 to TotalNotifyingApplyControls-1 do
  119.     if UpperCase(Item.Name) = UpperCase(NotifyingApplyControls[i]) then
  120.       Items.HandleMessage(TOptionsApplyNotifyMsg.Create(UpperCase(Item.Name), GUIToString(Item)));
  121.   AConfig[OptionName] := GUIToString(Item);
  122. end;
  123. procedure TACSHelper.ConfigToControl(const FormName, OptionName: string; AConfig: TProperties);
  124. var Form, Item: TItem; Prop: PProperty;
  125. begin
  126.   Form := GUIRoot.GetChildByName(FormName, True);
  127.   if not (Form is TGUIItem) then Exit;
  128.   Item := Form.GetChildByName(OptionName, True);
  129.   if not (Item is TGUIItem) then Exit;
  130. //  if TGUIItem(Item).Data is TTextListItems then
  131. //    TTextListItems(TGUIItem(Item).Data).VariantsText := AConfig.GetProperty(OptionName).Enumeration;
  132.   if (Item is TSwitchButton) then with Item as TSwitchButton do VariantIndex := StrToIntDef(AConfig[Name], VariantIndex) else
  133.     if (Item is TTrackBar) then with Item as TTrackBar do Value := StrToIntDef(AConfig[Name], Value) else
  134.       if (Item is TCheckBox) then (Item as TCheckBox).Checked := AConfig[OptionName] = OnOffStr[True] else
  135.         if (Item is TComboList) then begin
  136.           if Assigned((Item as TComboList).Items) and Assigned((Item as TComboList).Items.Items) then begin
  137.             Prop := AConfig.GetProperty(OptionName);
  138.             if Assigned(Prop) then (Item as TComboList).Items.Items.VariantsText := Prop^.Enumeration;
  139.             (Item as TComboList).Text := AConfig[OptionName];
  140.           end;
  141.         end else if (Item is TBaseList) then begin
  142.           Prop := AConfig.GetProperty(OptionName);
  143.           if Assigned(Prop) then (Item as TBaseList).VariantsText := Prop^.Enumeration;
  144.           (Item as TBaseList).Text := AConfig[OptionName];
  145.         end else if (Item is TTextGUIItem) then
  146.           (Item as TTextGUIItem).Text := AConfig[OptionName];
  147. end;
  148. constructor TACSHelper.Create(AItems: TItemsManager; AConfig: TProperties);
  149. begin
  150.   Config := AConfig;
  151.   Items  := AItems;
  152.   Items.RegisterItemClass(TGUIItem);
  153.   Items.RegisterItemClass(TGUIRootItem);
  154.   Items.RegisterItemClass(TGUIPoint);
  155.   Items.RegisterItemClass(TGUILine);
  156.   Items.RegisterItemClass(TCursorPicture);
  157.   Items.RegisterItemClass(TPanel);
  158.   Items.RegisterItemClass(TLabel);
  159.   Items.RegisterItemClass(TButton);
  160.   Items.RegisterItemClass(TSwitchButton);
  161.   Items.RegisterItemClass(ACSAdv.TSwitchLabel);
  162.   Items.RegisterItemClass(TCheckBox);
  163.   Items.RegisterItemClass(TProgressBar);
  164.   Items.RegisterItemClass(TSlider);
  165.   Items.RegisterItemClass(TEdit);
  166.   Items.RegisterItemClass(TList);
  167.   Items.RegisterItemClass(TComboList);
  168.   Items.RegisterItemClass(TWindow);
  169.   Items.RegisterItemClass(TCaptionArea);
  170.   Items.RegisterItemClass(TClientArea);
  171. end;
  172. destructor TACSHelper.Destroy;
  173. var i: Integer;
  174. begin
  175.   FormNames := nil;
  176.   for i := 0 to High(History) do History[i].Visibility := nil;
  177.   History := nil;
  178.   inherited;
  179. end;
  180. procedure TACSHelper.HandleMessage(const Msg: TMessage);
  181. var i: Integer;
  182. begin
  183.   if Msg is TSceneLoadedMsg then Initialize else if GUIRoot = nil then Exit;
  184. //  if Msg is TInputMessage then GUIRoot.BroadcastMessage(Msg) else
  185.     if not (Msg is TGUIMessage) then Exit;
  186.   if Msg.ClassType = TGUIClickMsg then HandleGUIClick((Msg as TGUIClickMsg).Item);
  187.   if Msg.ClassType = TGUIChangeMsg then with TGUIChangeMsg(Msg) do begin
  188.     Assert(Assigned(Item), Format('%S.%S: ', [ClassName, 'HandleMessage: Message of class %S contains undefined(nil) item', Msg.ClassName]));
  189.     for i := 0 to TotalImmediateApplyControls-1 do
  190.       if UpperCase(Item.Name) = UpperCase(ImmediateApplyControls[i]) then
  191.         Items.HandleMessage(TOptionsPreviewMsg.Create(UpperCase(Item.Name), GUIToString(Item)));
  192.   end;
  193. end;
  194. procedure TACSHelper.HandleGUIClick(const Item: TGUIItem);
  195. var Action: Integer; Arg: string;
  196. begin
  197.   if Item.Name = 'ForceQuit' then Items.HandleMessage(TForceQuitMsg.Create);
  198.   Action := GetCommand(Item.Name, Arg);
  199.   case Action of
  200.     aShow: if ControlExists(Arg) then begin
  201.       RememberState;
  202.       ConfigToForm(Arg, Config);
  203.       ShowForm(Arg, False);
  204.     end;
  205.     aShowSolely: if ControlExists(Arg) then begin
  206.       RememberState;
  207.       ConfigToForm(Arg, Config);
  208.       ShowForm(Arg, True);
  209.     end;
  210.     aToggle: if ControlExists(Arg) then ToggleControl(Arg);
  211.     aClose: HideControl(Arg);
  212.     aOK: if ControlExists(Arg) then begin
  213.       FormToConfig(Arg, Config);
  214.       ShowPreviousState;
  215.       Items.HandleMessage(TOptionsApplyMsg.Create(UpperCase(Arg)));
  216.     end;
  217.     aApply: if ControlExists(Arg) then begin
  218.       FormToConfig(Arg, Config);
  219.       Items.HandleMessage(TOptionsApplyMsg.Create(UpperCase(Arg)));
  220.     end;
  221.     aCancel: if ControlExists(Arg) then begin
  222.       ConfigToForm(Arg, Config);
  223.       ShowPreviousState;
  224.     end;
  225.     aReset: if ControlExists(Arg) then ResetConfig(Arg, DefaultConfig);
  226.     aBack: ShowPreviousState;
  227.   end;
  228. end;
  229. procedure TACSHelper.HideAllForms;
  230. var i: Integer;
  231. begin
  232.   for i := 0 to TotalFormNames-1 do HideControl(FormNames[i]);
  233. end;
  234. function TACSHelper.ControlExists(const Name: string): Boolean;
  235. begin
  236.   Result := GUIRoot.GetChildByName(Name, True) <> nil;
  237. end;
  238. function TACSHelper.IsControlVisible(const Name: string; CheckHierarchy: Boolean): Boolean;
  239. var Item: TItem;
  240. begin
  241.   Item := GUIRoot.GetChildByName(Name, True);
  242.   Result := (Item is TGUIItem) and (isVisible in Item.State);
  243.   Item := Item.Parent;
  244.   if CheckHierarchy then while (Item is TGUIItem) or (Item is TDummyItem) do if not (Item is TDummyItem) then begin
  245.     Result := Result and (isVisible in Item.State);
  246.     Item := Item.Parent;
  247.   end;  
  248. end;
  249. procedure TACSHelper.ShowControl(const Name: string);
  250. var Item: TItem;
  251. begin
  252.   Item := GUIRoot.GetChildByName(Name, True);
  253.   while (Item is TGUIItem) or (Item is TDummyItem) do begin
  254.     if not (Item is TDummyItem) then Item.State := Item.State + [isVisible];
  255.     Item := Item.Parent;
  256.   end;
  257. end;
  258. procedure TACSHelper.HideControl(const Name: string);
  259. var Item: TItem;
  260. begin
  261.   Item := GUIRoot.GetChildByName(Name, True);
  262.   if Item is TGUIItem then Item.State := Item.State - [isVisible];
  263. end;
  264. procedure TACSHelper.ToggleControl(const Name: string);
  265. var Item: TItem;
  266. begin
  267.   Item := GUIRoot.GetChildByName(Name, True);
  268.   if not (Item is TGUIItem) then Exit;
  269.   if isVisible in Item.State then
  270.     Item.State := Item.State - [isVisible] else
  271.       Item.State := Item.State + [isVisible];
  272. end;
  273. procedure TACSHelper.EnableControl(const Name: string);
  274. var Item: TGUIItem;
  275. begin
  276.   Item := Items.Root.GetChildByName(Name, True) as TGUIItem;
  277.   if Item is TGUIItem then Item.State := Item.State - [isProcessing];
  278. end;
  279. procedure TACSHelper.DisableControl(const Name: string);
  280. var Item: TGUIItem;
  281. begin
  282.   Item := Items.Root.GetChildByName(Name, True) as TGUIItem;
  283.   if Item is TGUIItem then Item.State := Item.State + [isProcessing];
  284. end;
  285. procedure TACSHelper.SetControlText(const Name, Text: string);
  286. var Item: TItem;
  287. begin
  288.   Item := Items.Root.GetChildByName(Name, True);
  289.   if Item is TTextGUIItem then (Item as TTextGUIItem).Text := Text else
  290. //   if Item is TEdit then (Item as TEdit).Text := Text;
  291. end;
  292. function TACSHelper.GetControlText(const Name: string): string;
  293. var Item: TItem;
  294. begin
  295.   Result := '';
  296.   Item := GUIRoot.GetChildByName(Name, True);
  297.   if Item is TTextGUIItem then Result := (Item as TTextGUIItem).Text else
  298. //   if Item is TEdit then Result := (Item as TEdit).Text;
  299. end;
  300. function TACSHelper.GUIToString(Item: TItem): string;
  301. begin
  302.   Result := '';
  303.   if Item = nil then Exit;
  304.   if (Item is TSwitchButton) then Result := IntToStr((Item as TSwitchButton).VariantIndex) else
  305.     if (Item is TTrackBar) then Result := IntToStr((Item as TTrackBar).Value) else
  306.       if (Item is TCheckBox) then Result := OnOffStr[(Item as TCheckBox).Checked] else
  307. //        if (Item is TBaseList) then Result := (Item as TBaseList).Text else
  308.           if (Item is TTextGUIItem) then Result := (Item as TTextGUIItem).Text;
  309. end;
  310. procedure TACSHelper.ResetConfig(const FormName: string; ADefaultConfig: TProperties);
  311. begin
  312.   inherited;
  313.   Items.HandleMessage(TOptionsApplyMsg.Create(UpperCase(FormName)));
  314. end;
  315. procedure TACSHelper.AddForm(const FormName: string);
  316. begin
  317.   {$IFDEF LOGGING}
  318.   if (GUIRoot <> nil) and (GUIRoot.GetChildByName(FormName, True) = nil) then Log.Log(ClassName + '.AddForm: GUI container item "' + FormName + '" doest not exists', lkWarning);
  319.   {$ENDIF}
  320.   
  321.   if Length(FormNames) <= TotalFormNames then SetLength(FormNames, Length(FormNames) + FormNamesCapacityStep);
  322.   FormNames[TotalFormNames] := FormName;
  323.   Inc(TotalFormNames);
  324. end;
  325. procedure TACSHelper.LoadForms(const FileName: string);
  326. var cf: Text; s: string;
  327. begin
  328. {$I-}
  329.   Assign(cf, FileName); Reset(cf);
  330.   if IOResult <> 0 then begin
  331.     {$IFDEF LOGGING} Log.Log(ClassName + '.LoadForms: Error opening file "' + FileName + '"', lkError); {$ENDIF}
  332.     Exit;
  333.   end;
  334.   while not EOF(cf) do begin
  335.     Readln(cf, s);
  336.     if IOResult <> 0 then begin
  337.       {$IFDEF LOGGING} Log.Log(ClassName + '.Load: Error reading from file "' + FileName + '"', lkError); {$ENDIF}
  338.       Break;
  339.     end else if s <> '' then AddForm(s);
  340.   end;
  341.   Close(cf);
  342. end;
  343. procedure TACSHelper.ShowForm(const FormName: string; Solely: Boolean);
  344. begin
  345.   if ControlExists(FormName) then begin
  346.     if Solely then HideAllForms;
  347.     ShowControl(FormName);
  348.   end;  
  349. end;
  350. procedure TACSHelper.RememberState;
  351. var i: Integer; Item: TItem; Changed: Boolean;
  352. begin
  353. // Check if something changed
  354.   Changed := TotalHistory = 0;
  355.   if TotalHistory > 0 then for i := 0 to TotalFormNames-1 do begin
  356.     Item := GUIRoot.GetChildByName(FormNames[i], True);
  357.     if History[TotalHistory-1].Visibility[i] <> (Item is TGUIItem) and (isVisible in Item.State) then begin
  358.       Changed := True;
  359.       Break;
  360.     end;
  361.   end;
  362.   if not Changed then Exit;
  363.   if Length(History) <= TotalHistory then SetLength(History, Length(History) + FormNamesCapacityStep);
  364.   SetLength(History[TotalHistory].Visibility, TotalFormNames);
  365.   for i := 0 to TotalFormNames-1 do begin
  366.     Item := GUIRoot.GetChildByName(FormNames[i], True);
  367.     History[TotalHistory].Visibility[i] := (Item is TGUIItem) and (isVisible in Item.State);
  368.   end;
  369.   Inc(TotalHistory);
  370. end;
  371. procedure TACSHelper.ShowPreviousState;
  372. var i: Integer;
  373. begin
  374.   if TotalHistory > 0 then Dec(TotalHistory) else Exit;
  375.   for i := 0 to High(History[TotalHistory].Visibility) do
  376.     if History[TotalHistory].Visibility[i] then ShowControl(FormNames[i]) else HideControl(FormNames[i]); 
  377. end;
  378. function TACSHelper.GetControlFormName(const Name: string): string;
  379. //var Item: TGUIItem;
  380. begin
  381.   Assert(False, '');
  382. {  Result := '';
  383.   while not (Item is TGUIItem) do begin
  384.     if FindForm(Item.Name) <> nil then begin
  385.       Result := Item.Name;
  386.       Exit;
  387.     end;
  388.   end;}
  389. end;
  390. function TACSHelper.IsWithinGUI(AX, AY: Single): Boolean;
  391. begin
  392.   Result := GUIRoot.IsWithinGUI(AX, AY);
  393. end;
  394. end.