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

游戏引擎

开发平台:

Delphi

  1. (*
  2.  @Abstract(Advanced ACS GUI library unit)
  3.  (C) 2006 George "Mirage" Bakhtadze. <a href="http://www.casteng.com">www.casteng.com</a> <br>
  4.  The source code may be used under either MPL 1.1 or LGPL 2.1 license. See included license.txt file <br>
  5.  Unit contains advanced GUI controls
  6. *)
  7. {$Include GDefines.inc}
  8. unit ACSAdv;
  9. interface
  10. uses
  11.   TextFile, 
  12.   SysUtils, BaseTypes, Basics, Props, MarkUp, BaseGraph, BaseClasses, BaseMsg, GUIMsg, Models, ACSBase, ACS;
  13. type
  14.   TTextListItems = class(TModel)
  15.   private
  16.     FItems: BaseTypes.TAnsiStringArray;
  17.     FTotalItems: Integer;
  18.     FVariantsText: string;
  19.     procedure SetVariantsText(const Value: string);                            // Splits text to variants by "&". "\" treat as ""
  20.     function GetItem(Index: Integer): string;
  21.     procedure SetItem(Index: Integer; const Value: string);
  22.   protected
  23.     procedure DoSort(Ascending: Boolean; CompareFunc: TStringCompareDelegate); virtual;
  24.   public
  25.     procedure GetProperties(const Result: Props.TProperties); override;
  26.     procedure SetProperties(Properties: Props.TProperties); override;
  27.     function IndexOf(const Value: string): Integer;
  28.     procedure Add(const Value: string);
  29.     procedure Remove(Index: Integer);
  30.     procedure Sort(Ascending: Boolean; CompareFunc: TStringCompareDelegate);
  31.     property VariantsText: string read FVariantsText write SetVariantsText;
  32.     property TotalItems: Integer read FTotalItems write FTotalItems;
  33.     property Items[Index: Integer]: string read GetItem write SetItem; default;
  34.   end;
  35.   TBaseList = class(TTextGUIItem)
  36.   private
  37.     function GetVariantsText: string;
  38.     procedure SetVariantsText(const Value: string);
  39.   protected
  40.     FItemIndex: Integer;
  41.     FItems: TTextListItems;
  42.     function GetModel: TModel; override;
  43.     procedure SetItemIndex(Value: Integer); virtual;
  44.   public
  45.     constructor Create(AManager: TItemsManager); override;
  46.     destructor Destroy; override;
  47.     procedure AddProperties(const Result: Props.TProperties); override;
  48.     procedure SetProperties(Properties: Props.TProperties); override;
  49.     property Items: TTextListItems read FItems;
  50.     property ItemIndex: Integer read FItemIndex write SetItemIndex;
  51.     property VariantsText: string read GetVariantsText write SetVariantsText;
  52.   end;
  53.   TSwitchLabel = class(TBaseList)
  54.     function GUIHandleMessage(const Msg: TMessage): Boolean; override;
  55.     procedure Draw; override;
  56.   end;
  57.   TList = class(TBaseList)
  58.   protected
  59.     BottomVisible, HoverItem: Integer;
  60.     FocusedBarColor, SelectedBarColor: TColor;
  61.     function GetSizeAdjustable: Boolean; override;
  62.     procedure SetItemIndex(Value: Integer); override;
  63.   public
  64.     TopVisible: Integer;
  65.     constructor Create(AManager: TItemsManager); override;
  66.     function GUIHandleMessage(const Msg: TMessage): Boolean; override;
  67.     procedure AddProperties(const Result: Props.TProperties); override;
  68.     procedure SetProperties(Properties: Props.TProperties); override;
  69.     function GetItemAt(AX, AY: Single): Integer; virtual;
  70.     function GetItemByMouse(AX, AY: Single): Integer; virtual;
  71.     procedure Draw; override;
  72.   end;
  73.   TTable = class(TBaseList)
  74.   protected   
  75.   public
  76. {    procedure AddProperties(const Result: Props.TProperties); override;
  77.     procedure SetProperties(Properties: Props.TProperties); override;
  78.     procedure Draw; override;}
  79.   end;
  80.   TComboList = class(TLabel)
  81.   private
  82.     function GetItems: TBaseList;
  83.   protected
  84.     function GetModel: TModel; override;
  85.     function FindListControl(PopupControl: TGUIItem): TBaseList;
  86.     function GetPopupControl: TGUIItem;
  87.     procedure HandleClick(Button, MX, MY: Integer); override;
  88.   public
  89.     function GUIHandleMessage(const Msg: TMessage): Boolean; override;
  90.     procedure ReturnMessage(const Msg: TMessage); override;
  91.     procedure AddProperties(const Result: Props.TProperties); override;
  92.     procedure SetProperties(Properties: Props.TProperties); override;
  93.     property Items: TBaseList read GetItems;
  94.   end;
  95.   // Returns list of classes introduced by the unit
  96.   function GetUnitClassList: TClassArray;
  97. implementation
  98. function GetUnitClassList: TClassArray;
  99. begin
  100.   Result := GetClassList([TSwitchLabel, TList, TComboList]);
  101. end;
  102. { TTextListItems }
  103. procedure TTextListItems.SetVariantsText(const Value: string);
  104. begin
  105.   FVariantsText := Value;
  106.   TotalItems := SplitA(FVariantsText, '&', FItems, False);
  107. end;
  108. function TTextListItems.GetItem(Index: Integer): string;
  109. begin
  110.   Assert((Index >= 0) and (Index < TotalItems), ClassName + '.SetItem: Index out of range');
  111.   Result := FItems[Index];
  112. end;
  113. procedure TTextListItems.SetItem(Index: Integer; const Value: string);
  114. begin
  115.   Assert((Index >= 0) and (Index < TotalItems), ClassName + '.SetItem: Index out of range');
  116.   FItems[Index] := Value;
  117. end;
  118. procedure TTextListItems.GetProperties(const Result: Props.TProperties);
  119. begin
  120.   Result.Add('Variants', vtString, [], FVariantsText, '');
  121. end;
  122. procedure TTextListItems.SetProperties(Properties: Props.TProperties);
  123. begin
  124.   if Properties.Valid('Variants') then VariantsText := Properties['Variants'];
  125. end;
  126. function TTextListItems.IndexOf(const Value: string): Integer;
  127. var i: Integer;
  128. begin
  129.   Result := -1;
  130.   for i := 0 to TotalItems-1 do if FItems[i] = Value then begin
  131.     Result := i;
  132.     Exit;
  133.   end;
  134. end;
  135. procedure TTextListItems.Add(const Value: string);
  136. begin
  137.   if Length(FItems) <= TotalItems then SetLength(FItems, Length(FItems) + CollectionsCapacityStep);
  138.   FItems[FTotalItems] := Value;
  139.   Inc(FTotalItems);
  140. end;
  141. procedure TTextListItems.Remove(Index: Integer);
  142. begin
  143.   while Index < TotalItems-1 do begin
  144.     FItems[Index] := FItems[Index+1];
  145.     Inc(Index);
  146.   end;
  147.   FItems[Index] := '';
  148.   Dec(FTotalItems);
  149. end;
  150. procedure TTextListItems.DoSort(Ascending: Boolean; CompareFunc: TStringCompareDelegate);
  151. var i, j: Integer;
  152. begin
  153.   if Assigned(CompareFunc) then begin
  154.   end else
  155.     Basics.QuickSortStr(TotalItems, FItems);
  156.   j := FTotalItems-1;
  157.   if not Ascending then for i := 0 to FTotalItems div 2-1 do begin
  158.     Swap(FItems[i], FItems[j]);
  159.     Dec(j);
  160.   end;
  161. end;
  162. procedure TTextListItems.Sort(Ascending: Boolean; CompareFunc: TStringCompareDelegate);
  163. begin
  164.   DoSort(Ascending, CompareFunc);
  165. end;
  166. { TBaseList }
  167. function TBaseList.GetVariantsText: string;
  168. begin
  169.   if Assigned(FItems) then Result := FItems.VariantsText else Result := '';
  170. end;
  171. procedure TBaseList.SetVariantsText(const Value: string);
  172. begin
  173.   if Assigned(FItems) then FItems.VariantsText := Value;
  174. end;
  175. function TBaseList.GetModel: TModel;
  176. begin
  177.   Result := FItems;
  178. end;
  179. constructor TBaseList.Create(AManager: TItemsManager);
  180. begin
  181.   inherited;
  182.   FItems := TTextListItems.Create;
  183. end;
  184. destructor TBaseList.Destroy;
  185. begin
  186.   FreeAndNil(FItems);
  187.   inherited;
  188. end;
  189. procedure TBaseList.AddProperties(const Result: Props.TProperties);
  190. begin
  191.   inherited;
  192.   if not Assigned(Result) then Exit;
  193.   Result.Add('Item index', vtInt, [], IntToStr(ItemIndex), '');
  194. end;
  195. procedure TBaseList.SetProperties(Properties: Props.TProperties);
  196. begin
  197.   inherited;
  198.   if Properties.Valid('Item index') then ItemIndex := StrToIntDef(Properties['Item index'], 0);
  199. end;
  200. procedure TBaseList.SetItemIndex(Value: Integer);
  201. begin
  202.   if (Value < 0) or (Value >= FItems.TotalItems) then Value := -1;
  203.   if (FItemIndex <> Value) and isVisibleAndEnabled then ReturnMessage(TGUIChangeMsg.Create(Self));
  204.   FItemIndex := Value;
  205.   if FItemIndex = -1 then Text := '' else Text := FItems[FItemIndex];
  206. end;
  207. { TSwitchLabel }
  208. procedure TSwitchLabel.Draw;
  209. begin
  210.   inherited;
  211.   Screen.SetColor(Color);
  212.   Screen.SetFont(Font);
  213.   DrawText(0, 0);
  214. end;
  215. function TSwitchLabel.GUIHandleMessage(const Msg: TMessage): Boolean;
  216. begin
  217.   Result := inherited GUIHandleMessage(Msg);
  218.   if not Result then Exit;
  219.   if Msg.ClassType = TMouseClickMsg then with TMouseClickMsg(Msg) do begin
  220.     if (Button = IK_MOUSELEFT) and Hover then
  221.       if ItemIndex < FItems.TotalItems-1 then ItemIndex := ItemIndex + 1 else ItemIndex := 0;
  222.   end;
  223. end;
  224. { TList }
  225. function TList.GetSizeAdjustable: Boolean;
  226. begin
  227.   Result := False;
  228. end;
  229. procedure TList.SetItemIndex(Value: Integer);
  230. begin
  231.   inherited;
  232.   if ItemIndex < TopVisible    then TopVisible := ItemIndex;
  233.   if ItemIndex > BottomVisible then if ItemIndex = BottomVisible + 1 then Inc(TopVisible) else TopVisible := ItemIndex;
  234. end;
  235. constructor TList.Create(AManager: TItemsManager);
  236. begin
  237.   inherited;
  238.   HoverItem := -1;
  239. end;
  240. function TList.GUIHandleMessage(const Msg: TMessage): Boolean;
  241. var MX, MY: Single;
  242. begin
  243.   if (Msg.ClassType = TMouseMoveMsg) or (Msg.ClassType = TMouseDownMsg) then with TMouseMoveMsg(Msg) do begin
  244.     MX := X; MY := Y;
  245.     ScreenToClient(MX, MY);
  246.   end;
  247.   Result := inherited GUIHandleMessage(Msg);
  248.   if not Result then Exit;
  249.   if (Msg.ClassType = TMouseDownMsg) or
  250.      (Msg.ClassType = TMouseMoveMsg) then with TMouseMsg(Msg) do begin
  251.     if Hover then HoverItem := GetItemAt(MX, MY) else HoverItem := -1;
  252.     if Pushed then begin
  253.       ItemIndex := GetItemByMouse(MX, MY);
  254.       UpdateVisualParameters;
  255.     end;
  256.   end;
  257. end;
  258. procedure TList.AddProperties(const Result: Props.TProperties);
  259. begin
  260.   inherited;
  261.   if not Assigned(Result) then Exit;
  262.   AddColorProperty(Result, 'ColorSelected bar', SelectedBarColor);
  263.   AddColorProperty(Result, 'ColorFocused bar',  FocusedBarColor);
  264. end;
  265. procedure TList.SetProperties(Properties: Props.TProperties);
  266. begin
  267.   inherited;
  268.   SetColorProperty(Properties, 'ColorSelected bar', SelectedBarColor);
  269.   SetColorProperty(Properties, 'ColorFocused bar',  FocusedBarColor);
  270. end;
  271. procedure TList.Draw;
  272. var i, CurPos: Integer; Tag: TTag; LY, w, h: Single;
  273. begin
  274.   inherited;
  275.   LY := 0;
  276.   BottomVisible := TopVisible;
  277.   for i := MaxI(TopVisible, 0) to FItems.TotalItems-1 do begin
  278.     Font.GetTextExtent(FItems[i], w, h);
  279.     if i = ItemIndex then begin
  280.       if Focused then Screen.Color := FocusedBarColor else Screen.Color := SelectedBarColor;
  281.       Screen.Bar(0, LY, PxWidth, LY + h);
  282.       Screen.Color := FocusedColor;
  283.     end else if i = HoverItem then Screen.Color := HoverColor else Screen.Color := NormalColor;
  284.     Screen.SetFont(Font);
  285. //    DrawText(0, LY);
  286.     Screen.PutTextXY(0, LY, FItems[i]);
  287.     LY := LY + h;
  288.     if LY >= PxHeight then Exit else BottomVisible := i;
  289.   end;
  290. {  if Colored and (MarkUp <> nil) then begin
  291.     GetClearedText;
  292.     CurPos := 0;
  293.     Screen.MoveTo(0, 0);
  294.     for i := 0 to MarkUp.TotalTags-1 do begin
  295.       Tag := MarkUp.Tags[i];
  296.       if CurPos <> Tag.Position then begin
  297.         Screen.PutText(Copy(MarkUp.PureText, CurPos+1, Tag.Position-CurPos));
  298.         CurPos := Tag.Position;
  299.       end;
  300.       if Tag.ClassType = TMoveToTag     then with TMoveToTag(Tag)     do Screen.MoveTo(X, Y);
  301.       if Tag.ClassType = TColorTag      then with TColorTag(Tag)      do Screen.SetColor(Screen.Color and $FF000000 or Color);
  302.       if Tag.ClassType = TAlphaColorTag then with TAlphaColorTag(Tag) do Screen.SetColor(Color);
  303.       if Tag.ClassType = TColorResetTag then with TColorResetTag(Tag) do Screen.SetColor(Self.Color);
  304.     end;
  305.     Screen.PutText(Copy(MarkUp.PureText, CurPos+1, Length(MarkUp.PureText)));
  306.   end else   }
  307. end;
  308. function TList.GetItemAt(AX, AY: Single): Integer;
  309. var LY, w, h: Single;
  310. begin
  311.   Result := 0;
  312.   if AX < 0       then Result := miLeft;
  313.   if AX >= PxWidth  then Result := miRight;
  314.   if AY < 0       then Result := miUp;
  315.   if AY >= PxHeight then Result := miDown;
  316.   if Result <> 0 then Exit; 
  317.   LY := 0;
  318.   for Result := MaxI(TopVisible, 0) to FItems.TotalItems-1 do begin
  319.     Font.GetTextExtent(FItems[Result], w, h);
  320.     if (AY >= LY) and (AY < LY+h) then Exit;
  321.     LY := LY + h;
  322.     if LY >= PxHeight then Exit;
  323.   end;
  324.   Result := miDown;
  325. end;
  326. function TList.GetItemByMouse(AX, AY: Single): Integer;
  327. begin
  328.   if Pushed then AX := 0;
  329.   Result := GetItemAt(AX, AY);
  330.   if Result < 0 then if Pushed then begin
  331.     case Result of
  332.       miUp:   Result := MaxI(ItemIndex-1, 0);
  333.       miDown: Result := MinI(ItemIndex+1, FItems.TotalItems-1);
  334.       miLeft, miRight: Result := ItemIndex;
  335.    end;
  336.  end else Result := ItemIndex;
  337. end;
  338. { TComboList }
  339. const PopupListProp = 'Popup control';
  340. function TComboList.GetItems: TBaseList;
  341. var Item: TItem;
  342. begin
  343.   Item := GetPopupControl;
  344.   if Item is TBaseList then Result := Item as TBaseList else Result := nil;
  345. end;
  346. function TComboList.GetModel: TModel;
  347. var List: TBaseList;
  348. begin
  349.   List := FindListControl(GetPopupControl);
  350.   if List <> nil then Result := List.FItems else Result := nil;
  351. end;
  352. function TComboList.FindListControl(PopupControl: TGUIItem): TBaseList;
  353. function GetListChild(Item: TItem): TBaseList;
  354. var i: Integer;
  355. begin
  356.   Result := nil;
  357.   if Item is TBaseList then Result := TBaseList(Item) else
  358.     for i := 0 to Item.TotalChilds-1 do begin
  359.       Result := GetListChild(Item.Childs[i]);
  360.       if Result <> nil then Exit;
  361.     end;
  362. end;
  363. begin
  364.   Result := nil;
  365.   if PopupControl = nil then Exit;
  366.   Result := GetListChild(PopupControl);
  367. end;
  368. function TComboList.GetPopupControl: TGUIItem;
  369. var PopupList: TItem;
  370. begin
  371.   ResolveLink(PopupListProp, PopupList);
  372.   if PopupList is TGUIItem then Result := TGUIItem(PopupList) else Result := nil;
  373. end;
  374. procedure TComboList.HandleClick(Button, MX, MY: Integer);
  375. var PopupList: TGUIItem;
  376. begin
  377.   inherited;
  378.   if Hover and (Button = IK_MOUSELEFT) then begin
  379.     PopupList := GetPopupControl;
  380.     if PopupList <> nil then begin
  381.       PopupList.State := PopupList.State + [isVisible];
  382.       Height := PopupList.Height + Height * 0;
  383.     end;
  384.   end;
  385. end;
  386. function TComboList.GUIHandleMessage(const Msg: TMessage): Boolean;
  387. begin
  388.   Result := inherited GUIHandleMessage(Msg);
  389.   if not Result then Exit;
  390.   if Msg.ClassType = TMouseClickMsg then if Hover then with TMouseClickMsg(Msg) do HandleClick(Button, X, Y);
  391. end;
  392. procedure TComboList.ReturnMessage(const Msg: TMessage);
  393. var CallInherited: Boolean;
  394. begin
  395.   CallInherited := True;
  396.   if Msg.ClassType = TGUIClickMsg then with TGUIClickMsg(Msg) do begin
  397.     if Item is TBaseList then begin
  398.       CallInherited := False;
  399.       Text := TBaseList(Item).Text;
  400.       if GetPopupControl <> nil then GetPopupControl.State := GetPopupControl.State - [isVisible];
  401.     end;
  402.   end;
  403.   if CallInherited then inherited;
  404. end;
  405. procedure TComboList.AddProperties(const Result: Props.TProperties);
  406. begin
  407.   inherited;
  408.   AddItemLink(Result, PopupListProp, [], 'TGUIItem');
  409. end;
  410. procedure TComboList.SetProperties(Properties: Props.TProperties);
  411. begin
  412.   inherited;
  413.   if Properties.Valid(PopupListProp) then SetLinkProperty(PopupListProp, Properties[PopupListProp]);
  414. end;
  415. begin
  416.   GlobalClassList.Add('ACSAdv', GetUnitClassList);
  417. end.