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

游戏引擎

开发平台:

Delphi

  1. (*
  2.  @Abstract(CAST Engine DirectX 8 GUI items 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 ready to use GUI items such as button, label etc
  6. *)
  7. {$Include GDefines}
  8. {$Include C2Defines}
  9. unit C2GUIItems;
  10. interface
  11. uses
  12.   TextFile, 
  13.   Basics, Base3D, Props, BaseGraph,
  14.   C2Types, CAST2, C22D, Markup, C2Visual, C2GUI;
  15. type
  16.   TGUIPoint = class(TGUIItem)
  17.   end;
  18.   TGUILine = class(TGUIItem)
  19.     procedure Render; override;
  20.   end;
  21. {  TGUICursor = class(TUVGUIItem)
  22.     constructor Create; override;
  23.     procedure Render; override;
  24.     function ProcessInput(MX, MY: Single): Boolean; override;
  25.     procedure GetProperties(var Result: TProperties); override;
  26.     procedure SetProperties(Properties: TProperties); override;
  27.     procedure SetPosition(const AX, AY: Single); override;
  28.     procedure SetFrame(const Value: Integer); override;
  29.     procedure SetFrameRange(const AMin, AMax: Integer); virtual;
  30.     procedure SetWindow(const X1, Y1, X2, Y2: Single); virtual;
  31.   protected
  32.     CMinFrame, CMaxFrame: Integer;
  33.     HotX, HotY: Single;
  34.     WindowX1, WindowY1, WindowX2, WindowY2: Single;
  35.   end;}
  36.   TLabel = class(TWrappingText)
  37.     procedure Render; override;
  38.   end;
  39. (*  TSwitchLabel = class(TLabel)
  40. // Splits text to variants by "&". "\" threats as ""
  41.     Variants: TStringArray; TotalVariants: Integer;
  42.     procedure SetText(const AText: string); override;
  43.     procedure SetVariantIndex(const Value: Integer); virtual;
  44.     function ProcessInput(MX, MY: Single): Boolean; override;
  45.     procedure GetProperties(var Result: TProperties); override;
  46.     procedure SetProperties(Properties: TProperties); override;
  47.     function IndexOf(const Value: string): Integer; virtual;
  48.   protected
  49.     SWText: string;
  50.     FVariantIndex: Integer;
  51.   public
  52.     property VariantIndex: Integer read FVariantIndex write SetVariantIndex;
  53.   end;
  54.   TPanel = class(TUVGUIItem)
  55.     LineColor, LineHoverColor: Longword;
  56.     CurrentFrame: Integer;
  57.     procedure Render; override;
  58.     function ProcessInput(MX, MY: Single): Boolean; override;
  59.     procedure SetLineColor(const ALineColor: Longword);
  60.     procedure GetProperties(var Result: TProperties); override;
  61.     procedure SetProperties(Properties: TProperties); override;
  62.   protected
  63.     CurrentLineColor: Longword;
  64.   end;
  65.   TSwitchButton = class(TPanel)
  66.     constructor Create; override;
  67.     procedure SetFrame(const Value: Integer); override;
  68.     procedure SetFrameRange(const AMin, AMax: Integer); virtual;
  69.     procedure GetProperties(var Result: TProperties); override;
  70.     procedure SetProperties(Properties: TProperties); override;
  71.     function ProcessInput(MX, MY: Single): Boolean; override;
  72.   protected
  73.     MinSwitchFrame, MaxSwitchFrame: Integer;
  74.     function GetVariantIndex: Integer;
  75.     procedure SetVariantIndex(const Value: Integer);
  76.   public
  77.     property VariantIndex: Integer read GetVariantIndex write SetVariantIndex;
  78.   end;
  79.   TCheckBox = class(TPanel)
  80.     constructor Create; override;
  81.     function ProcessInput(MX, MY: Single): Boolean; override;
  82.     procedure GetProperties(var Result: TProperties); override;
  83.     procedure SetProperties(Properties: TProperties); override;
  84.   protected
  85.     FChecked: Boolean;
  86.     HoverFrame, CheckedFrame, HoverCheckedFrame: Integer;
  87.     procedure SetChecked(const Value: Boolean);
  88.   public
  89.     property Checked: Boolean read FChecked write SetChecked;
  90.   end;
  91.   TButton = class(TPanel)
  92.     Pressed: Boolean;
  93.     function ProcessInput(MX, MY: Single): Boolean; override;
  94.     procedure GetProperties(var Result: TProperties); override;
  95.     procedure SetProperties(Properties: TProperties); override;
  96.     procedure Process; override;
  97.   protected
  98.     HoverFrame, PressedFrame: Integer;
  99.     RepeatDelay, RepeatTimer: Integer;
  100.     RepeatsPerTick, RepeatsCounter: Single;
  101.   end;
  102.   TSlider = class(TUVGUIItem)
  103.     ValueColor, HoverValueColor: Longword;
  104.     ValueFrame: Integer;
  105.     Vertical, FreeChange, Tracking: Boolean;
  106.     constructor Create; override;
  107.     procedure Render; override;
  108.     function ProcessInput(MX, MY: Single): Boolean; override;
  109.     procedure GetProperties(var Result: TProperties); override;
  110.     procedure SetProperties(Properties: TProperties); override;
  111.     function SetValueByCoord(const MX, MY: Single): Boolean; virtual;
  112.   private
  113.     procedure SetMaxValue(const Value: Integer);
  114.     procedure SetValue(const Value: Integer);
  115.   protected
  116.     FValue, FMaxValue: Integer;
  117.     CurrentValueColor: Longword;
  118.   public
  119.     property Value: Integer read FValue write SetValue;
  120.     property MaxValue: Integer read FMaxValue write SetMaxValue;
  121.   end;*)
  122. implementation
  123. uses C2Tess2D;
  124. { TGUILine }
  125. procedure TGUILine.Render;
  126. var i, PCnt: Integer; Point: TGUIPoint;
  127. begin
  128.   Screen.SetViewport(Screen.ConstructViewport(X, Y, X + Width - 1, Y + Height - 1));
  129.   SetTechnique(CurTechnique);
  130.   PCnt := 0;
  131.   for i := 0 to TotalChilds-1 do if Childs[i] is TGUIPoint then begin
  132.     Point := Childs[i] as TGUIPoint;
  133.     Screen.SetColor(Point.CurrentColor);
  134.     if PCnt = 0 then Screen.MoveTo(Point.X, Point.Y) else Screen.LineTo(Point.X, Point.Y);
  135.     Inc(PCnt);
  136.   end;
  137.   inherited;
  138.   Screen.RestoreViewport;
  139. end;
  140. { TGUICursor }
  141. {constructor TGUICursor.Create;
  142. begin
  143.   inherited;
  144.   CMinFrame := 0; CMaxFrame := 0;
  145.   HotX := 0; HotY := 0;
  146.   SetWindow(-1, -1, -1, -1);
  147. end;
  148. function TGUICursor.GetProperties: TProperties;
  149. begin
  150.   Result := inherited GetProperties;
  151.   NewProperty(Result, 'Minimal frame number', ptInt32, Pointer(CMinFrame));
  152.   NewProperty(Result, 'Maximal frame number', ptInt32, Pointer(CMaxFrame));
  153.   NewProperty(Result, 'Hot X', ptSingle, Pointer(HotX));
  154.   NewProperty(Result, 'Hot Y', ptSingle, Pointer(HotY));
  155. end;
  156. function TGUICursor.SetProperties(AProperties: TProperties): Integer;
  157. begin
  158.   Result := -1;
  159.   SetFrameRange(Integer(GetPropertyValue(AProperties, 'Minimal frame number')), Integer(GetPropertyValue(AProperties, 'Maximal frame number')));
  160.   if inherited SetProperties(AProperties) < 0 then Exit;
  161.   HotX := Single(GetPropertyValue(AProperties, 'Hot X'));
  162.   HotY := Single(GetPropertyValue(AProperties, 'Hot Y'));
  163.   Result := 0;
  164. end;
  165. function TGUICursor.ProcessInput(MX, MY: Single): Boolean;
  166. begin
  167.   SetPosition(MX - HotX, MY - HotY);
  168.   Result := inherited ProcessInput(MX, MY);
  169. end;
  170. procedure TGUICursor.SetPosition(const AX, AY: Single);
  171. var NX, NY, WX1, WY1, WX2, WY2: Single;
  172. begin
  173.   if WindowX1 = -1 then WX1 := -HotX else WX1 := WindowX1-HotX;
  174.   if WindowY1 = -1 then WY1 := -HotY else WY1 := WindowY1-HotY;
  175.   if WindowX2 = -1 then WX2 := World.Renderer.RenderPars.ActualWidth-1-HotX else WX2 := WindowX2-HotX;
  176.   if WindowY2 = -1 then WY2 := World.Renderer.RenderPars.ActualHeight-1-HotY else WY2 := WindowY2-HotY;
  177.   NX := MinS(MaxS(AX, WX1), WX2) + 0.5;
  178.   NY := MinS(MaxS(AY, WY1), WY2) + 0.5;
  179.   inherited SetPosition(NX, NY);
  180. end;
  181. procedure TGUICursor.SetWindow(const X1, Y1, X2, Y2: Single);
  182. begin
  183.   WindowX1 := X1; WindowY1 := Y1; WindowX2 := X2; WindowY2 := Y2;
  184.   if WindowX1 > WindowX2 then Swap(WindowX1, WindowX2);
  185.   if WindowY1 > WindowY2 then Swap(WindowY1, WindowY2);
  186.   SetPosition(X, Y);
  187. end;
  188. procedure TGUICursor.SetFrame(const Value: Integer);
  189. begin
  190.   inherited SetFrame(MinI(MaxI(Value, CMinFrame), CMaxFrame));
  191.   NormalFrame := Frame;
  192. end;
  193. procedure TGUICursor.Render(const Screen: TScreen);
  194. begin
  195.   Screen.SetUV(UVMap[Frame]);
  196.   Screen.SetColor(CurrentColor);
  197.   Screen.SetRenderPasses(RenderPasses);
  198.   Screen.Bar(X, Y, X + Width, Y + Height);
  199.   inherited;
  200. end;
  201. procedure TGUICursor.SetFrameRange(const AMin, AMax: Integer);
  202. begin
  203.   CMinFrame := MinI(MaxI(AMin, 0), MaxFrame);
  204.   CMaxFrame := MinI(MaxI(AMax, 0), MaxFrame);
  205.   if CMinFrame > CMaxFrame then Swap(CMinFrame, CMaxFrame);
  206.   SetFrame(Frame);
  207. end;}
  208. { TLabel }
  209. procedure TLabel.Render;
  210. const Dg = 256;
  211. var i, j: Integer;
  212. begin
  213.   if CurTechnique = nil then Exit;
  214.   SetTechnique(CurTechnique);
  215.   if (Font = nil) or (RText = '') then Exit;
  216. //  Screen.DrawLine(Random(200), Random(200), Random(200), Random(200));
  217. //  Screen.Bar(Random(200), Random(200), Random(200), Random(200));
  218. {  for i := 0 to 15 do for j := 0 to 15 do begin
  219.     Screen.SetColor((i * 16 + (j * 16) shl 8) or $FF000000);
  220.     Screen.Bar(X + i*16, Y + j*16, X + i*16+14, Y + j*16+14);
  221.     Screen.SetColor(((15-i) * 16 + (j * 16) shl 16) or $FF000000);
  222.     Screen.Line(X + i*16, Y + j*16, X + i*16+14, Y + j*16+14);
  223.   end;
  224.   Screen.MoveTo(X + 100, Y);
  225.   for i := 0 to TicksProcessed and (Dg-1) do Screen.LineTo(X + Cos(i/Dg*2*pi)*100, Y + Sin(i/Dg*2*pi)*100);
  226.  }
  227. //  Screen.Bar(X, Y, X + 200, Y + Height);
  228.   Screen.SetColor(CurrentColor);
  229.   Screen.SetFont(Font.Font);
  230.   case WrapMode of
  231.     wmNone: if Colored then Screen.PutFormattedText(X, Y, RText) else Screen.PutText(X, Y, RText);
  232.     wmCut: ;
  233.     wmSimbolWrap, wmWordWrap: for i := 0 to TotalLines-1 do
  234.      if Colored then Screen.PutFormattedText(X, Y+i*LineHeight, Lines[i]) else Screen.PutText(X, Y+i*LineHeight, Lines[i]);
  235.     wmJustify: ;
  236.   end;
  237.   inherited;
  238. end;
  239. end.
  240. { TTextGUIItem }
  241. function TTextGUIItem.GetProperties: TProperties;
  242. begin
  243.   Result := inherited GetProperties;
  244. //  NewProperty(Result, 'Text', ptResource + World.ResourceManager.GetResourceClassIndex('TTextResource') shl 8, Pointer(TextRes));
  245.   NewProperty(Result, 'Text', ptLongString + Length(FText) shl 8, Pointer(FText));
  246.   NewProperty(Result, 'Colored', ptBoolean, Pointer(Colored));
  247.   NewProperty(Result, 'Font', ptGroupBegin, nil);
  248.     NewProperty(Result, 'UVMap', ptResource + World.ResourceManager.GetResourceClassIndex('TFontResource') shl 8, Pointer(FontRes));
  249.     NewProperty(Result, 'Characters mapping', ptResource + World.ResourceManager.GetResourceClassIndex('TCharMapResource') shl 8, Pointer(CharMapRes));
  250.     NewProperty(Result, 'X scale', ptSingle, Pointer(TextXScale));
  251.     NewProperty(Result, 'Y scale', ptSingle, Pointer(TextYScale));
  252.   NewProperty(Result, '', ptGroupEnd, nil);
  253. end;
  254. function TTextGUIItem.SetProperties(AProperties: TProperties): Integer;
  255. var Prop: TProperty; s: string;
  256. begin
  257.   Result := -1;
  258.   if inherited SetProperties(AProperties) < 0 then Exit;
  259.   FontRes := Integer(GetPropertyValue(AProperties, 'UVMap'));
  260.   CharMapRes := Integer(GetPropertyValue(AProperties, 'Characters mapping'));
  261.   TextXScale := Single(GetPropertyValue(AProperties, 'X scale'));
  262.   TextYScale := Single(GetPropertyValue(AProperties, 'Y scale'));
  263.   Colored := Boolean(GetPropertyValue(AProperties, 'Colored'));
  264.   if (FontRes >= 0) and (FontRes < World.ResourceManager.TotalResources) and (World.ResourceManager[FontRes] is TArrayResource) then
  265.    UVMap := TUVMap(World.ResourceManager[FontRes].Data);
  266.   if (CharMapRes >= 0) and (CharMapRes < World.ResourceManager.TotalResources) and (World.ResourceManager[CharMapRes] is TArrayResource) then
  267.    CharMap := TCharMap(World.ResourceManager[CharMapRes].Data);
  268.   if GetProperty(AProperties, 'Text', Prop) then begin
  269.     if Prop.ValueType and $FF = ptLongString then begin
  270.       RetrieveLongString(Prop.Value, Prop.ValueType shr 8, s);
  271.       SetText(s);
  272.     end else if Prop.ValueType and $FF = ptResource then begin
  273.       SetTextRes(Integer(Prop.Value));
  274.     end;
  275.   end;
  276.   Result := 0;
  277. end;
  278. function TTextGUIItem.GetClearedText: string;
  279. begin
  280.   if Colored then begin
  281.     if Markup = nil then Markup := TSimpleMarkup.Create;
  282.     Markup.FormattedText := RText;
  283.     Result := Markup.ClearedText
  284.   end else Result := RText;
  285. end;
  286. procedure TTextGUIItem.SetText(const AText: string);
  287. begin
  288.   FText := AText; RText := FText;
  289.   Width := GetTextWidth;
  290. end;
  291. procedure TTextGUIItem.SetTextRes(const ATextRes: Integer);
  292. begin
  293.   TextRes := ATextRes;
  294.   if (TextRes = -1) or (TextRes >= World.ResourceManager.TotalResources) or not (World.ResourceManager[TextRes] is TTextResource) then
  295.    SetText('') else
  296.     SetText(TTextResource(World.ResourceManager[TextRes]).GetText);
  297. end;
  298. function TTextGUIItem.GetTextWidth: Single;
  299. var i: Integer;
  300. begin
  301.   Result := 0;
  302.   if (FontRes = -1) or (CharMapRes = -1) or (not (World.ResourceManager[CharMapRes] is TCharMapResource)) then Exit;
  303.   for i := 0 to Length(CText)-1 do
  304. //   Result := Result + TUVMap(World.ResourceManager[FontRes].Data)[Ord(FText[i+1])-32].W * TextXScale;
  305.    Result := Result + TUVMap(World.ResourceManager[FontRes].Data)[TCharMap(World.ResourceManager[CharMapRes].Data)[Ord(CText[i+1])]].W * TextXScale;
  306. end;
  307. destructor TTextGUIItem.Free;
  308. begin
  309.   if Markup <> nil then Markup.Free;
  310. end;
  311. { TWrappingText }
  312. function TWrappingText.GetProperties: TProperties;
  313. begin
  314.   Result := inherited GetProperties;
  315.   NewProperty(Result, 'Text wrapping mode', ptInt32, Pointer(WrapMode));
  316. end;
  317. function TWrappingText.SetProperties(AProperties: TProperties): Integer;
  318. begin
  319.   Result := -1;
  320.   WrapMode := Integer(GetPropertyValue(AProperties, 'Text wrapping mode'));
  321.   if inherited SetProperties(AProperties) < 0 then Exit;
  322.   Result := 0;
  323. end;
  324. procedure TWrappingText.SetText(const AText: string);
  325. procedure DoSimbolWrap;
  326. var cc: Integer; cw: Single;
  327. begin
  328.   LineHeight := 0;
  329.   if (UVMap = nil) or (CharMap = nil) then Exit;
  330.   TotalLines := 0;
  331.   if CText = '' then Exit;
  332.   cc := 1; cw := 0;
  333.   Inc(TotalLines); SetLength(Lines, TotalLines);
  334.   Lines[TotalLines-1] := CText[cc];
  335.   cw := UVMap[CharMap[Ord(CText[cc])]].W * TextXScale;
  336.   Inc(cc); 
  337.   while cc <= Length(CText) do begin
  338.     if LineHeight < UVMap[CharMap[Ord(CText[cc])]].H * TextYScale then LineHeight := UVMap[CharMap[Ord(CText[cc])]].H * TextYScale;
  339.     cw := cw + UVMap[CharMap[Ord(CText[cc])]].W * TextXScale;
  340.     if (cw > Width) then begin
  341.       Inc(TotalLines); SetLength(Lines, TotalLines);
  342.       Lines[TotalLines-1] := CText[cc];
  343.       cw := 0;
  344.     end else Lines[TotalLines-1] := Lines[TotalLines-1] + CText[cc];
  345.     Inc(cc);
  346.   end;
  347.   Height := LineHeight * TotalLines;
  348. end;
  349. procedure DoWordWrap;         // ToFix: Separators now can violate bounds
  350. const SeparatorChars = ' +-*/<>'#10#13;          
  351. var cc, CurLineWords: Integer; cw, WordW: Single; CurWord: string;
  352. begin
  353.   LineHeight := 0; TotalLines := 0;
  354.   if (UVMap = nil) or (CharMap = nil) or (CText = '') or (MarkUp = nil) then Exit;
  355.   cc := 1; cw := 0;
  356.   Inc(TotalLines); SetLength(Lines, TotalLines);
  357.   Lines[TotalLines-1] := '';
  358.   CurLineWords := 0;
  359.   CurWord := Markup.GetTagStrAtPos(cc-1) + CText[cc];
  360.   WordW := UVMap[CharMap[Ord(CText[cc])]].W * TextXScale;
  361.   Inc(cc);
  362.   while cc <= Length(CText)+1 do begin
  363.     if (cc <= Length(CText)) and (LineHeight < UVMap[CharMap[Ord(CText[cc])]].H * TextYScale) then
  364.      LineHeight := UVMap[CharMap[Ord(CText[cc])]].H * TextYScale;
  365.     if (cc = Length(CText)+1) or (Pos(CText[cc], SeparatorChars) > 0) then begin   // Separator encountered
  366.       if (cw + WordW > Width) and (CurLineWords > 0) then begin                    // New line
  367. {        if cw + UVMap[CharMap[Ord(CText[cc])]].W * TextXScale > Width then begin  // Where to put separator character?
  368.           CurWord := CurWord + CText[cc];
  369.           WordW := WordW + UVMap[CharMap[Ord(CText[cc])]].W * TextXScale;
  370.         end else Lines[TotalLines-1] := Lines[TotalLines-1] + CText[cc];}
  371.         Inc(TotalLines); SetLength(Lines, TotalLines);
  372.         Lines[TotalLines-1] := Markup.GetResultTagStrAtPos(cc-1-Length(CurWord));
  373.         if CurWord <> '' then CurLineWords := 1 else CurLineWords := 0;
  374.         cw := 0;
  375.       end else begin                                                               // Line continued
  376.         if CurWord <> '' then Inc(CurLineWords);
  377.       end;
  378.       Lines[TotalLines-1] := Lines[TotalLines-1] + CurWord;
  379.       cw := cw + WordW;
  380.       if cc <= Length(CText) then begin                                            // Add the separator character
  381.         Lines[TotalLines-1] := Lines[TotalLines-1] + Markup.GetTagStrAtPos(cc-1) + CText[cc];
  382.         cw := cw + UVMap[CharMap[Ord(CText[cc])]].W * TextXScale;
  383.       end;
  384.       CurWord := ''; WordW := 0;
  385.     end else begin                                                                 // Alphabetical character
  386.       CurWord := CurWord + Markup.GetTagStrAtPos(cc-1) + CText[cc];
  387.       WordW := WordW + UVMap[CharMap[Ord(CText[cc])]].W * TextXScale;
  388.     end;
  389.     Inc(cc);
  390.   end;
  391.   Height := LineHeight * TotalLines;
  392. end;
  393. begin
  394.   FText := AText; RText := FText; 
  395.   case WrapMode of
  396.     wmNone: inherited;
  397.     wmCut: ;
  398.     wmSimbolWrap: DoSimbolWrap;
  399.     wmWordWrap: DoWordWrap;
  400.     wmJustify: ;
  401.   end;
  402. end;
  403. { TPanel }
  404. procedure TPanel.SetLineColor(const ALineColor: Longword);
  405. begin
  406.   LineColor := ALineColor; CurrentLineColor := LineColor;
  407. end;
  408. procedure TPanel.Render(const Screen: TScreen);
  409. begin
  410.   Screen.SetUV(UVMap[Frame]);
  411.   Screen.SetColor(CurrentColor);
  412.   Screen.SetRenderPasses(RenderPasses);
  413.   Screen.Bar(X, Y, X + Width, Y + Height);
  414.   if CurrentLineColor > 0 then begin
  415.     Screen.SetColor(CurrentLineColor);
  416.     Screen.SetUV(StdUV);
  417.     Screen.MoveTo(X, Y);
  418.     Screen.LineTo(X+Width, Y);
  419.     Screen.LineTo(X+Width, Y+Height);
  420.     Screen.LineTo(X, Y+Height);
  421.     Screen.LineTo(X, Y);
  422.   end;
  423.   inherited;
  424. end;
  425. function TPanel.GetProperties: TProperties;
  426. begin
  427.   Result := inherited GetProperties;
  428.   NewProperty(Result, 'Lines color', ptColor32, Pointer(LineColor));
  429.   NewProperty(Result, 'Lines hover color', ptColor32, Pointer(LineHoverColor));
  430. end;
  431. function TPanel.SetProperties(AProperties: TProperties): Integer;
  432. begin
  433.   Result := -1;
  434.   if inherited SetProperties(AProperties) < 0 then Exit;
  435.   SetLineColor(Longword(GetPropertyValue(AProperties, 'Lines color')));
  436.   LineHoverColor := Longword(GetPropertyValue(AProperties, 'Lines hover color'));
  437.   Result := 0;
  438. end;
  439. function TPanel.ProcessInput(MX, MY: Single): Boolean;
  440. begin
  441.   Result := inherited ProcessInput(MX, MY);
  442.   if Hover then begin
  443.     CurrentLineColor := LineHoverColor;
  444.   end else begin
  445.     CurrentLineColor := LineColor;
  446.   end;
  447. end;
  448. { TSwitchButton }
  449. constructor TSwitchButton.Create(AName: TShortName; AWorld: TWorld; AParent: TItem);
  450. begin
  451.   inherited;
  452.   CurrentFrame := 0;
  453. end;
  454. procedure TSwitchButton.SetFrameRange(const AMin, AMax: Integer);
  455. begin
  456.   MinSwitchFrame := MinI(MaxI(AMin, 0), MaxFrame);
  457.   MaxSwitchFrame := MinI(MaxI(AMax, 0), MaxFrame);
  458.   if MinSwitchFrame > MaxSwitchFrame then Swap(MinSwitchFrame, MaxSwitchFrame);
  459.   SetFrame(Frame);
  460. end;
  461. procedure TSwitchButton.SetFrame(const Value: Integer);
  462. begin
  463.   inherited SetFrame(MinI(MaxI(Value, MinSwitchFrame), MaxSwitchFrame));
  464.   NormalFrame := Frame; CurrentFrame := Frame;
  465. end;
  466. function TSwitchButton.ProcessInput(MX, MY: Single): Boolean;
  467. var i: Integer;
  468. begin
  469.   Result := inherited ProcessInput(MX, MY);
  470.   if Hover then for i := 0 to GetGUI.Commands.TotalCommands-1 do
  471.    if (GetGUI.Commands.Commands[i].CommandID = cmdLeftMouseClick) then begin
  472.      Inc(CurrentFrame);
  473.      if EOnChange then GetGUI.Commands.Add(cmdGUIChange, [Integer(Self)]);
  474.      Break;
  475.    end;
  476.   if CurrentFrame > MaxSwitchFrame then CurrentFrame := MinSwitchFrame;
  477. //  if (HoverFrame <> NormalFrame) and IsInBounds(MX, MY) then Inc(CurrentFrame);
  478.   Frame := CurrentFrame;
  479. end;
  480. function TSwitchButton.GetProperties: TProperties;
  481. begin
  482.   Result := inherited GetProperties;
  483.   NewProperty(Result, 'Minimal frame number', ptInt32, Pointer(MinSwitchFrame));
  484.   NewProperty(Result, 'Maximal frame number', ptInt32, Pointer(MaxSwitchFrame));
  485. end;
  486. function TSwitchButton.SetProperties(AProperties: TProperties): Integer;
  487. begin
  488.   Result := -1;
  489.   if inherited SetProperties(AProperties) < 0 then Exit;
  490.   SetFrameRange(Integer(GetPropertyValue(AProperties, 'Minimal frame number')), Integer(GetPropertyValue(AProperties, 'Maximal frame number')));
  491.   Result := 0;
  492. end;
  493. function TSwitchButton.GetVariantIndex: Integer;
  494. begin
  495.   Result := Frame - MinSwitchFrame;
  496. end;
  497. procedure TSwitchButton.SetVariantIndex(const Value: Integer);
  498. begin
  499.   Frame := MinSwitchFrame + Value;
  500. end;
  501. { TUVGUIItem }
  502. constructor TUVGUIItem.Create(AName: TShortName; AWorld: TWorld; AParent: TItem);
  503. begin
  504.   inherited;
  505.   UVMapRes := -1; UVMap := GetStdUVMap;
  506. end;
  507. function TUVGUIItem.GetProperties: TProperties;
  508. begin
  509.   Result := inherited GetProperties;
  510.   NewProperty(Result, 'UV map', ptResource + World.ResourceManager.GetResourceClassIndex('TFontResource') shl 8, Pointer(UVMapRes));
  511.   NewProperty(Result, 'Normal frame', ptInt32, Pointer(NormalFrame));
  512. end;
  513. function TUVGUIItem.SetProperties(AProperties: TProperties): Integer;
  514. begin
  515.   Result := -1;
  516.   if inherited SetProperties(AProperties) < 0 then Exit;
  517.   UVMapRes := Integer(GetPropertyValue(AProperties, 'UV map'));
  518.   NormalFrame := Integer(GetPropertyValue(AProperties, 'Normal frame'));
  519.   if (UVMapRes < 0) or (UVMapRes >= World.ResourceManager.TotalResources) or not (World.ResourceManager[UVMapRes] is TArrayResource) then UVMap := GetStdUVMap else begin
  520.     MaxFrame := (World.ResourceManager[UVMapRes] as TArrayResource).TotalElements - 1;
  521.     UVMap := (World.ResourceManager[UVMapRes] as TArrayResource).Data;
  522.   end;
  523.   Frame := NormalFrame;
  524. //  SetDimensions(UVMap[Frame].W, UVMap[Frame].H);
  525.   Result := 0;
  526. end;
  527. procedure TUVGUIItem.SetFrame(const Value: Integer);
  528. begin
  529.   if (Value = FFrame) or (Value > MaxFrame) then Exit;
  530.   FFrame := Value;
  531. end;
  532. { TSlider }
  533. constructor TSlider.Create(AName: TShortName; AWorld: TWorld; AParent: TItem);
  534. begin
  535.   inherited;
  536.   MaxValue := 100; Value := 0;
  537. end;
  538. function TSlider.GetProperties: TProperties;
  539. begin
  540.   Result := inherited GetProperties;
  541.   NewProperty(Result, 'Value color', ptColor32, Pointer(ValueColor));
  542.   NewProperty(Result, 'Hover value color', ptColor32, Pointer(HoverValueColor));
  543.   NewProperty(Result, 'Value frame', ptInt32, Pointer(ValueFrame));
  544.   NewProperty(Result, 'Value', ptInt32, Pointer(FValue));
  545.   NewProperty(Result, 'Max value', ptInt32, Pointer(FMaxValue));
  546.   NewProperty(Result, 'Vertical', ptBoolean, Pointer(Vertical));
  547.   NewProperty(Result, 'Free change', ptBoolean, Pointer(FreeChange));
  548.   NewProperty(Result, 'Tracking', ptBoolean, Pointer(Tracking));
  549. end;
  550. function TSlider.SetProperties(AProperties: TProperties): Integer;
  551. begin
  552.   Result := -1;
  553.   if inherited SetProperties(AProperties) < 0 then Exit;
  554.   ValueColor := Longword(GetPropertyValue(AProperties, 'Value color'));
  555.   HoverValueColor := Longword(GetPropertyValue(AProperties, 'Hover value color'));
  556.   ValueFrame := Integer(GetPropertyValue(AProperties, 'Value frame'));
  557.   SetValue(Integer(GetPropertyValue(AProperties, 'Value')));
  558.   SetMaxValue(Integer(GetPropertyValue(AProperties, 'Max value')));
  559.   Vertical := Boolean(GetPropertyValue(AProperties, 'Vertical'));
  560.   FreeChange := Boolean(GetPropertyValue(AProperties, 'Free change'));
  561.   Tracking := Boolean(GetPropertyValue(AProperties, 'Tracking'));
  562.   Result := 0;
  563. end;
  564. function TSlider.ProcessInput(MX, MY: Single): Boolean;
  565. var i: Integer;
  566. begin
  567.   Result := inherited ProcessInput(MX, MY);
  568.   if Hover then begin
  569.     CurrentValueColor := HoverValueColor;
  570.     for i := 0 to GetGUI.Commands.TotalCommands-1 do begin
  571.       if LMousePressed then begin
  572.         if (GetGUI.Commands.Commands[i].CommandID = cmdLeftMouseUp) then
  573.          if SetValueByCoord(MX, MY) then if EOnChange then GetGUI.Commands.Add(cmdGUIChange, [Integer(Self)]);
  574.       end;
  575.     end;
  576.   end else begin
  577.     CurrentValueColor := ValueColor;
  578.   end;
  579.   if LMousePressed then if Tracking then if SetValueByCoord(MX, MY) then
  580.    if EOnChange then GetGUI.Commands.Add(cmdGUIChange, [Integer(Self)]);
  581. end;
  582. procedure TSlider.Render(const Screen: TScreen);
  583. var Temp: Single; UV: TUV;
  584. begin
  585.   Screen.SetRenderPasses(RenderPasses);
  586.   if FMaxValue = 0 then Temp := 0 else Temp := FValue / FMaxValue;
  587.   if Vertical then begin
  588.     UV.U := UVMap[Frame].U; UV.W := UVMap[Frame].W;
  589.     UV.V := UVMap[Frame].V; UV.H := UVMap[Frame].H * (1-Temp);
  590.     Screen.SetUV(UV);
  591.     Screen.SetColor(CurrentColor);
  592.     Screen.Bar(X, Y, X + Width, Y + Height - Height * Temp);
  593.     UV.U := UVMap[ValueFrame].U; UV.W := UVMap[ValueFrame].W;
  594.     UV.V := UVMap[ValueFrame].V + UVMap[ValueFrame].H * (1-Temp); UV.H := UVMap[ValueFrame].H * Temp;
  595.     Screen.SetUV(UV);
  596.     Screen.SetColor(CurrentValueColor);
  597.     Screen.Bar(X, Y + Height - Height * Temp, X + Width, Y + Height);
  598.   end else begin
  599.     UV.U := UVMap[Frame].U; UV.W := UVMap[Frame].W * Temp;
  600.     UV.V := UVMap[Frame].V; UV.H := UVMap[Frame].H;
  601.     Screen.SetUV(UV);
  602.     Screen.SetColor(CurrentColor);
  603.     Screen.Bar(X, Y, X + Width * Temp, Y + Height);
  604.     UV.U := UVMap[ValueFrame].U + UVMap[ValueFrame].W * Temp; UV.W := UVMap[ValueFrame].W * (1 - Temp);
  605.     UV.V := UVMap[ValueFrame].V; UV.H := UVMap[ValueFrame].H;
  606.     Screen.SetUV(UV);
  607.     Screen.SetColor(CurrentValueColor);
  608.     Screen.Bar(X + Width * Temp, Y, X + Width, Y + Height);
  609.   end;
  610.   inherited;
  611. end;
  612. procedure TSlider.SetMaxValue(const Value: Integer);
  613. begin
  614.   FMaxValue := MaxI(0, Value);
  615. end;
  616. procedure TSlider.SetValue(const Value: Integer);
  617. begin
  618.   FValue := MaxI(0, MinI(MaxValue, Value));
  619. end;
  620. function TSlider.SetValueByCoord(const MX, MY: Single): Boolean;
  621. var OldValue: Integer;
  622. begin
  623.   Result := False;
  624.   if not FreeChange then Exit;
  625.   OldValue := Value;
  626.   if Vertical then begin
  627.     if Height = 0 then Value := 0 else Value := Trunc(0.5 + (Y + Height - MY) / Height * MaxValue);
  628.   end else begin
  629.     if Width = 0 then Value := 0 else Value := Trunc(0.5 + (MX - X) / Width * MaxValue);
  630.   end;
  631.   Result := OldValue <> Value;
  632. end;
  633. { TCheckBox }
  634. constructor TCheckBox.Create(AName: TShortName; AWorld: TWorld; AParent: TItem);
  635. begin
  636.   inherited;
  637.   Checked := False;
  638.   CurrentFrame := NormalFrame;
  639. end;
  640. procedure TCheckBox.SetChecked(const Value: Boolean);
  641. begin
  642.   FChecked := Value;
  643.   if FChecked then Frame := CheckedFrame else Frame := NormalFrame;
  644. end;
  645. function TCheckBox.GetProperties: TProperties;
  646. begin
  647.   Result := inherited GetProperties;
  648.   NewProperty(Result, 'Hover frame', ptInt32, Pointer(HoverFrame));
  649.   NewProperty(Result, 'Checked frame', ptInt32, Pointer(CheckedFrame));
  650.   NewProperty(Result, 'Hover checked frame', ptInt32, Pointer(HoverCheckedFrame));
  651.   NewProperty(Result, 'Checked', ptBoolean, Pointer(Checked));
  652. end;
  653. function TCheckBox.SetProperties(AProperties: TProperties): Integer;
  654. begin
  655.   Result := -1;
  656.   if inherited SetProperties(AProperties) < 0 then Exit;
  657.   HoverFrame := Integer(GetPropertyValue(AProperties, 'Hover frame'));
  658.   CheckedFrame := Integer(GetPropertyValue(AProperties, 'Checked frame'));
  659.   HoverCheckedFrame := Integer(GetPropertyValue(AProperties, 'Hover checked frame'));
  660.   SetChecked(Boolean(GetPropertyValue(AProperties, 'Checked')));
  661.   Result := 0;
  662. end;
  663. function TCheckBox.ProcessInput(MX, MY: Single): Boolean;
  664. var i: Integer;
  665. begin
  666.   Result := inherited ProcessInput(MX, MY);
  667.   if Hover then begin
  668.     for i := 0 to GetGUI.Commands.TotalCommands-1 do begin
  669.       if (GetGUI.Commands.Commands[i].CommandID = cmdLeftMouseClick) then begin
  670.         SetChecked(not Checked);
  671.         if EOnChange then GetGUI.Commands.Add(cmdGUIChange, [Integer(Self)]);
  672.       end; 
  673.     end;
  674.     if FChecked then Frame := HoverCheckedFrame else Frame := HoverFrame;
  675.   end else begin
  676.     if FChecked then Frame := CheckedFrame else Frame := NormalFrame;
  677.   end;
  678. end;
  679. { TButton }
  680. function TButton.GetProperties: TProperties;
  681. begin
  682.   Result := inherited GetProperties;
  683.   NewProperty(Result, 'Hover frame', ptInt32, Pointer(HoverFrame));
  684.   NewProperty(Result, 'Pressed frame', ptInt32, Pointer(PressedFrame));
  685.   NewProperty(Result, 'Repeating delay', ptInt32, Pointer(RepeatDelay));
  686.   NewProperty(Result, 'Repeats per tick', ptSingle, Pointer(RepeatsPerTick));
  687. end;
  688. function TButton.SetProperties(AProperties: TProperties): Integer;
  689. begin
  690.   Result := -1;
  691.   if inherited SetProperties(AProperties) < 0 then Exit;
  692.   HoverFrame := Integer(GetPropertyValue(AProperties, 'Hover frame'));
  693.   PressedFrame := Integer(GetPropertyValue(AProperties, 'Pressed frame'));
  694.   RepeatDelay := Integer(GetPropertyValue(AProperties, 'Repeating delay'));
  695.   RepeatsPerTick := Single(GetPropertyValue(AProperties, 'Repeats per tick'));
  696.   RepeatsCounter := 0;
  697.   Result := 0;
  698. end;
  699. function TButton.ProcessInput(MX, MY: Single): Boolean;
  700. begin
  701.   Result := inherited ProcessInput(MX, MY);
  702. //  if Transparent and (Parent <> nil) and (Parent is TButton) then LMousePressed := TGUIItem(Parent).LMousePressed;
  703.   Pressed := LMousePressed;
  704.   if Pressed then Frame := PressedFrame else if Hover then Frame := HoverFrame else Frame := NormalFrame;
  705. end;
  706. function TButton.Process: Boolean;
  707. var WasPressed: Boolean;
  708. begin
  709.   WasPressed := LMousePressed;
  710.   Result := inherited Process;
  711.   if LMousePressed then begin
  712.     if not WasPressed then begin
  713.       RepeatTimer := RepeatDelay;
  714.       RepeatsCounter := 0;
  715.     end else if RepeatTimer > 0 then Dec(RepeatTimer) else begin
  716.       RepeatsCounter := RepeatsCounter + RepeatsPerTick;
  717.       while RepeatsCounter >= 1 do begin
  718.         if EOnClick then GetGUI.Commands.Add(cmdGUIClick, [Integer(Self)]);
  719.         RepeatsCounter := RepeatsCounter - 1;
  720.       end;
  721.     end;
  722.   end else RepeatTimer := RepeatDelay;
  723. end;
  724. { TSwitchLabel }
  725. function TSwitchLabel.ProcessInput(MX, MY: Single): Boolean;
  726. var i: Integer;
  727. begin
  728.   Result := inherited ProcessInput(MX, MY);
  729.   if Hover then for i := 0 to GetGUI.Commands.TotalCommands-1 do
  730.    if (GetGUI.Commands.Commands[i].CommandID = cmdLeftMouseClick) then begin
  731.      if VariantIndex < TotalVariants-1 then VariantIndex := VariantIndex + 1 else VariantIndex := 0;
  732.      if EOnChange then GetGUI.Commands.Add(cmdGUIChange, [Integer(Self)]);
  733.      Break;
  734.    end;
  735. end;
  736. procedure TSwitchLabel.SetText(const AText: string);
  737. begin
  738.   SWText := AText;
  739.   TotalVariants := Split(SWText, '&', Variants, False);
  740.   VariantIndex := 0;
  741. end;
  742. procedure TSwitchLabel.SetVariantIndex(const Value: Integer);
  743. begin
  744.   if (Value >= 0) and (Value < TotalVariants) then FVariantIndex := Value;
  745.   if FVariantIndex >= Length(Variants) then Exit;
  746.   inherited SetText(Variants[FVariantIndex]);
  747.   FText := SWText;
  748.   if WrapMode = wmNone then Width := GetTextWidth;
  749. end;
  750. function TSwitchLabel.GetProperties: TProperties;
  751. begin
  752.   Result := inherited GetProperties;
  753.   NewProperty(Result, 'Variant index', ptInt32, Pointer(VariantIndex));
  754. end;
  755. function TSwitchLabel.SetProperties(AProperties: TProperties): Integer;
  756. begin
  757.   if inherited SetProperties(AProperties) < 0 then Exit;
  758.   VariantIndex := Integer(GetPropertyValue(AProperties, 'Variant index'));
  759.   Result := 0;
  760. end;
  761. function TSwitchLabel.IndexOf(const Value: string): Integer;
  762. var i: Integer;
  763. begin
  764.   Result := -1;
  765.   for i := 0 to TotalVariants-1 do if Variants[i] = Value then begin
  766.     Result := i;
  767.     Exit;
  768.   end;
  769. end;
  770. end.