diff --git a/Client/UfrmRegionControl.lfm b/Client/UfrmRegionControl.lfm new file mode 100644 index 0000000..8b3d16b --- /dev/null +++ b/Client/UfrmRegionControl.lfm @@ -0,0 +1,350 @@ +object frmRegionControl: TfrmRegionControl + Left = 367 + Height = 390 + Top = 268 + Width = 620 + Caption = 'Region Control' + ClientHeight = 390 + ClientWidth = 620 + OnCreate = FormCreate + OnDestroy = FormDestroy + OnShow = FormShow + Position = poOwnerFormCenter + LCLVersion = '0.9.25' + object Panel1: TPanel + Height = 360 + Width = 160 + Anchors = [akTop, akLeft, akBottom] + Caption = 'Panel1' + ClientHeight = 360 + ClientWidth = 160 + TabOrder = 0 + object Label1: TLabel + Left = 5 + Height = 14 + Top = 137 + Width = 150 + Align = alTop + BorderSpacing.Left = 4 + BorderSpacing.Right = 4 + Caption = 'Area:' + ParentColor = False + end + object pnlAreaControls: TPanel + Left = 5 + Height = 82 + Top = 273 + Width = 150 + Align = alBottom + BorderSpacing.Around = 4 + BevelOuter = bvNone + ClientHeight = 82 + ClientWidth = 150 + TabOrder = 0 + object lblX: TLabel + Left = 4 + Height = 14 + Top = 32 + Width = 7 + Caption = 'X' + Enabled = False + ParentColor = False + end + object lblY: TLabel + Left = 4 + Height = 14 + Top = 60 + Width = 7 + Caption = 'Y' + Enabled = False + ParentColor = False + end + object btnAddArea: TSpeedButton + Left = 30 + Height = 22 + Hint = 'Add area' + Width = 23 + Color = clBtnFace + Glyph.Data = { + 36040000424D3604000000000000360000002800000010000000100000000100 + 2000000000000004000064000000640000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000003A8C44FF368940FF32873CFF2F84 + 37FF000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000459653FF419950FF7DC28FFF96D0A6FF96CFA6FF78BE + 89FF368D42FF2C8134FF00000000000000000000000000000000000000000000 + 0000000000004D9C5DFF64B478FFA8DBB5FF87CC98FF66BC7DFF64BA7CFF86CB + 98FFA5D9B4FF58AA6BFF2C8134FF000000000000000000000000000000000000 + 000056A366FF6AB97DFFA8DBB2FF60BC77FF5CBA73FF59B870FF59B56FFF58B5 + 6FFF5BB774FFA5D9B3FF5AAA6CFF2C8234FF0000000000000000000000000000 + 000053AB68FFAADDB4FF64C179FF5FBE71FF60BC77FFFFFFFFFFFFFFFFFF59B8 + 70FF58B56EFF5CB774FFA6DAB4FF388F43FF00000000000000000000000061AC + 75FF8ACC98FF89D396FF6BC67AFF63C170FF55AB65FFFFFFFFFFFFFFFFFF59B8 + 70FF59B870FF5BB972FF85CC97FF7BBE8DFF308539FF000000000000000065AF + 7AFFA9DDB3FF7DCF8AFF75CC81FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFF59B870FF67BE7DFF9CD4ABFF34883DFF000000000000000069B2 + 7EFFB6E2BEFF8BD597FF7AC986FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFF59B870FF69C17EFF9DD4AAFF388B42FF00000000000000006DB5 + 83FFACDDB6FFA6DFAFFF81CB8CFF7CC986FF6EBD79FFFFFFFFFFFFFFFFFF5BAC + 6AFF60BC77FF5CBA73FF8BD199FF80C592FF3C8E47FF00000000000000000000 + 000085C797FFD2EED7FF95D9A0FF8AD394FF7FC889FFFFFFFFFFFFFFFFFF79CD + 85FF6BC37CFF6FC77EFFACDFB5FF459E57FF0000000000000000000000000000 + 000070B887FFAADAB7FFD8F1DCFF92D89DFF88CD93FF84CC8EFF8BD496FF8AD4 + 95FF83D28EFFAFE0B7FF6BB97DFF489856FF0000000000000000000000000000 + 00000000000070B887FFAFDCBBFFDCF2E0FFB6E4BDFF9BDBA5FF96D9A0FFA5DF + AFFFC0E8C5FF79C28AFF509E5FFF000000000000000000000000000000000000 + 0000000000000000000071B887FF94CEA4FFC3E6CBFFCFEBD4FFC9E9CEFFAFDD + B8FF6DB97FFF58A569FF00000000000000000000000000000000000000000000 + 0000000000000000000000000000000000006EB684FF6AB380FF67B17CFF63AE + 77FF000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000 + } + NumGlyphs = 0 + OnClick = btnAddAreaClick + ShowHint = True + ParentShowHint = False + end + object btnDeleteArea: TSpeedButton + Left = 59 + Height = 22 + Hint = 'Delete area' + Width = 23 + Color = clBtnFace + Glyph.Data = { + 36040000424D3604000000000000360000002800000010000000100000000100 + 2000000000000004000064000000640000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000003853BEFF3551BDFF304BBCFF2E4E + B8FF000000000000000000000000000000000000000000000000000000000000 + 000000000000000000004255C6FF3C52CCFF757AE8FF8F92EEFF8F92EEFF7178 + E4FF334DC1FF2B4AB7FF00000000000000000000000000000000000000000000 + 0000000000004959CBFF5C65E0FFA1A6F5FF7E86EFFF5B63E9FF595DE7FF7D84 + EEFF9EA0F4FF515DD7FF2B4AB7FF000000000000000000000000000000000000 + 00005361CFFF616BE3FFA1ACF5FF545FECFF505CEAFF4D59E9FF4E59E6FF4C56 + E6FF5056E6FF9EA2F4FF5460D6FF2A4AB8FF0000000000000000000000000000 + 00004B56DBFFA2ABF6FF5664F0FF5266EEFF4D59E9FF4D59E9FF4D59E9FF4D59 + E9FF4C58E6FF525AE6FF9FA3F5FF3450C4FF0000000000000000000000005C62 + D7FF818CEEFF7E91F7FF5D73F3FF4D59E9FF4D59E9FF4D59E9FF4D59E9FF4D59 + E9FF4D59E9FF4F5BE9FF7B83F0FF757BE2FF2E4BBAFF00000000000000005F63 + DAFFA1ABF7FF7086F8FF6882F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFF4D59E9FF5C66EAFF969CF1FF3250BCFF00000000000000006469 + DBFFAFB9F9FF7F93FAFF7085F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFF4D59E9FF5E6AEEFF969DF1FF364FBEFF0000000000000000676A + DEFFA5AFF5FF9DABFAFF778CF0FF545FECFF545FECFF545FECFF545FECFF545F + ECFF545FECFF6377F2FF818EF4FF787FE9FF3A53C0FF00000000000000000000 + 00007D83EAFFCDD4FCFF8B9DFAFF7E93F7FF758AEEFF6C84F6FF6C84F6FF6C84 + F6FF6C84F6FF6379F3FFA4AFF8FF3E4FD0FF0000000000000000000000000000 + 00006A69E0FFA3A7F3FFD4DBFDFF879AFAFF7F91F0FF7A8EF1FF7F94F8FF7E92 + F9FF768CF8FFA8B6F8FF636EE3FF4557C7FF0000000000000000000000000000 + 0000000000006A69E0FFAAADF2FFD8DCFDFFAEBAFAFF91A3FAFF8B9DFAFF9CA9 + FBFFBAC7FCFF707BE9FF4C5BCCFF000000000000000000000000000000000000 + 000000000000000000006A6ADFFF8E93EDFFBEC3F8FFCCD3F9FFC4CBF9FFAAB4 + F4FF6670E2FF535ED1FF00000000000000000000000000000000000000000000 + 000000000000000000000000000000000000686ADDFF6364DCFF6164DAFF5D63 + D9FF000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000 + } + NumGlyphs = 0 + OnClick = btnDeleteAreaClick + ShowHint = True + ParentShowHint = False + end + object btnClearArea: TSpeedButton + Left = 87 + Height = 22 + Hint = 'Delete all areas' + Width = 23 + Color = clBtnFace + Glyph.Data = { + 36040000424D3604000000000000360000002800000010000000100000000100 + 2000000000000004000064000000640000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000F1FF0000F1FF0000F1FF0000F1FF0000EFFF0000 + EFFF0000EDFF0000EDFF00000000000000000000000000000000000000000000 + 0000000000000000F5FF1A20F5FF3C4CF9FF3A49F8FF3847F8FF3545F8FF3443 + F7FF3242F7FF141BF1FF0000EDFF000000000000000000000000000000000000 + 00000000F7FF1D23F9FF4453FAFF2429F9FF1212F7FF0F0FF6FF0C0CF5FF0909 + F5FF161BF5FF3343F7FF141BF1FF0000EDFF0000000000000000000000000000 + F9FF1F25FAFF4A58FBFF4247FBFFC9C9FDFF3B3BF9FF1313F7FF1010F6FF3333 + F7FFC5C5FDFF3035F7FF3444F7FF141BF2FF0000EDFF00000000000000000000 + FBFF4F5DFDFF3237FBFFCBCBFEFFF2F2FFFFEBEBFEFF3B3BF9FF3939F8FFEAEA + FEFFF1F1FEFFC5C5FDFF181DF6FF3343F7FF0000EFFF00000000000000000000 + FDFF525FFDFF2828FCFF4747FCFFECECFFFFF2F2FFFFECECFFFFECECFEFFF1F1 + FFFFEAEAFEFF3434F7FF0B0BF5FF3545F8FF0000EFFF00000000000000000000 + FDFF5562FEFF2C2CFDFF2929FCFF4848FCFFEDEDFFFFF2F2FFFFF2F2FFFFECEC + FEFF3A3AF9FF1212F7FF0F0FF6FF3848F8FF0000F1FF00000000000000000000 + FDFF5764FEFF3030FDFF2D2DFDFF4B4BFCFFEDEDFFFFF2F2FFFFF2F2FFFFECEC + FFFF3D3DF9FF1616F8FF1313F7FF3C4BF8FF0000F1FF00000000000000000000 + FFFF5A67FEFF3333FEFF5050FDFFEDEDFFFFF3F3FFFFEDEDFFFFEDEDFFFFF2F2 + FFFFECECFEFF3E3EFAFF1717F8FF3F4EF9FF0000F1FF00000000000000000000 + FFFF5B68FFFF4347FEFFCFCFFFFFF3F3FFFFEDEDFFFF4C4CFCFF4A4AFCFFECEC + FFFFF2F2FFFFCACAFEFF2A2FFAFF4251FAFF0000F3FF00000000000000000000 + FFFF262BFFFF5D6AFFFF585BFFFFCFCFFFFF5252FEFF2F2FFDFF2C2CFDFF4B4B + FCFFCCCCFEFF484CFBFF4957FBFF1D23F9FF0000F5FF00000000000000000000 + 00000000FFFF262BFFFF5D6AFFFF4347FFFF3434FEFF3232FEFF3030FDFF2D2D + FDFF383CFCFF4F5DFCFF1F25FAFF0000F7FF0000000000000000000000000000 + 0000000000000000FFFF262BFFFF5C69FFFF5B68FFFF5A67FEFF5865FEFF5663 + FEFF5461FEFF2227FCFF0000FBFF000000000000000000000000000000000000 + 000000000000000000000000FFFF0000FFFF0000FFFF0000FFFF0000FDFF0000 + FDFF0000FDFF0000FDFF00000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000 + } + NumGlyphs = 0 + OnClick = btnClearAreaClick + ShowHint = True + ParentShowHint = False + end + object seX1: TSpinEdit + Left = 20 + Height = 23 + Top = 29 + Width = 50 + Enabled = False + OnChange = seX1Change + TabOrder = 0 + end + object seX2: TSpinEdit + Left = 84 + Height = 23 + Top = 29 + Width = 50 + Enabled = False + OnChange = seX1Change + TabOrder = 1 + end + object seY1: TSpinEdit + Left = 20 + Height = 23 + Top = 56 + Width = 50 + Enabled = False + OnChange = seX1Change + TabOrder = 2 + end + object seY2: TSpinEdit + Left = 84 + Height = 23 + Top = 56 + Width = 50 + Enabled = False + OnChange = seX1Change + TabOrder = 3 + end + end + object vstArea: TVirtualStringTree + Left = 5 + Height = 118 + Top = 151 + Width = 150 + Align = alClient + BorderSpacing.Left = 4 + BorderSpacing.Right = 4 + BorderSpacing.Bottom = 4 + BorderStyle = bsSingle + Header.MainColumn = -1 + Header.Options = [hoColumnResize, hoDrag] + TabOrder = 1 + TreeOptions.PaintOptions = [toShowButtons, toShowDropmark, toThemeAware, toUseBlendedImages] + TreeOptions.SelectionOptions = [toFullRowSelect] + OnChange = vstAreaChange + OnGetText = vstAreaGetText + Columns = <> + end + object vstGroups: TVirtualStringTree + Left = 1 + Height = 136 + Top = 1 + Width = 158 + Align = alTop + Header.Options = [hoAutoResize, hoVisible] + Header.Style = hsFlatButtons + PopupMenu = pmGroup + TabOrder = 2 + TreeOptions.MiscOptions = [toCheckSupport, toFullRepaintOnResize, toInitOnSave, toToggleOnDblClick, toWheelPanning] + TreeOptions.PaintOptions = [toShowButtons, toShowDropmark, toThemeAware, toUseBlendedImages] + TreeOptions.SelectionOptions = [toFullRowSelect] + OnChange = vstGroupsChange + OnEditing = vstGroupsOnEditing + OnGetText = vstGroupsGetText + OnNewText = vstGroupsNewText + Columns = < + item + Width = 158 + WideText = 'Groups' + end> + end + end + object Panel2: TPanel + Left = 160 + Height = 361 + Width = 460 + Anchors = [akTop, akLeft, akRight, akBottom] + Caption = 'Panel2' + ClientHeight = 361 + ClientWidth = 460 + TabOrder = 1 + object sbArea: TScrollBox + Left = 1 + Height = 359 + Top = 1 + Width = 458 + Align = alClient + TabOrder = 0 + object pbArea: TPaintBox + Height = 105 + Width = 105 + OnMouseDown = pbAreaMouseDown + OnMouseMove = pbAreaMouseMove + OnPaint = pbAreaPaint + end + end + end + object Panel3: TPanel + Height = 30 + Top = 360 + Width = 620 + Anchors = [akLeft, akRight, akBottom] + ClientHeight = 30 + ClientWidth = 620 + TabOrder = 2 + object btnExit: TButton + Left = 551 + Height = 22 + Top = 4 + Width = 64 + Anchors = [akTop, akRight] + Caption = 'Exit' + OnClick = btnCloseClick + TabOrder = 0 + end + object btnSave: TButton + Left = 480 + Height = 22 + Top = 4 + Width = 64 + Anchors = [akTop, akRight] + Caption = 'Save' + Enabled = False + OnClick = btnSaveClick + TabOrder = 1 + end + end + object pmGroup: TPopupMenu + left = 48 + top = 43 + object mnuAddGroup: TMenuItem + Caption = 'Add' + OnClick = acAddGroup + end + object mnuRemoveGroup: TMenuItem + Caption = 'Remove' + OnClick = accRemoveGroup + end + end +end diff --git a/Client/UfrmRegionControl.pas b/Client/UfrmRegionControl.pas new file mode 100644 index 0000000..8e4243b --- /dev/null +++ b/Client/UfrmRegionControl.pas @@ -0,0 +1,524 @@ +(* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at + * http://www.opensource.org/licenses/cddl1.php. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at + * http://www.opensource.org/licenses/cddl1.php. If applicable, + * add the following below this CDDL HEADER, with the fields enclosed + * by brackets "[]" replaced with your own identifying * information: + * Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * + * Portions Copyright 2008 Andreas Schneider + *) +unit UfrmRegionControl; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, CheckLst, + VirtualTrees, ExtCtrls, ImagingComponents, StdCtrls, Buttons, Spin, LCLIntf, + math, UPlatformTypes, UEnhancedMemoryStream, Menus,contnrs, UInterfaces, + URectList; + +type + TAreaMoveType = (amLeft, amTop, amRight, amBottom); + TAreaMove = set of TAreaMoveType; + + { TfrmRegionControl } + + TfrmRegionControl = class(TForm) + btnAddArea: TSpeedButton; + btnClearArea: TSpeedButton; + btnDeleteArea: TSpeedButton; + btnExit: TButton; + btnSave: TButton; + Label1: TLabel; + lblX: TLabel; + lblY: TLabel; + mnuAddGroup: TMenuItem; + mnuRemoveGroup: TMenuItem; + Panel1: TPanel; + Panel2: TPanel; + Panel3: TPanel; + pbArea: TPaintBox; + pnlAreaControls: TPanel; + pmGroup: TPopupMenu; + sbArea: TScrollBox; + seX1: TSpinEdit; + seX2: TSpinEdit; + seY1: TSpinEdit; + seY2: TSpinEdit; + vstGroups: TVirtualStringTree; + vstArea: TVirtualStringTree; + procedure acAddGroup(Sender: TObject); + procedure accRemoveGroup(Sender: TObject); + procedure btnAddAreaClick(Sender: TObject); + procedure btnClearAreaClick(Sender: TObject); + procedure btnCloseClick(Sender: TObject); + procedure btnDeleteAreaClick(Sender: TObject); + procedure btnSaveClick(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure FormDestroy(Sender: TObject); + procedure FormShow(Sender: TObject); + procedure pbAreaMouseDown(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + procedure pbAreaMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer + ); + procedure pbAreaPaint(Sender: TObject); + procedure seX1Change(Sender: TObject); + procedure vstAreaChange(Sender: TBaseVirtualTree; Node: PVirtualNode); + procedure vstAreaGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; + Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString); + procedure vstGroupsChange(Sender: TBaseVirtualTree; Node: PVirtualNode); + procedure vstGroupsGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; + Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString); + procedure vstGroupsNewText(Sender: TBaseVirtualTree; Node: PVirtualNode; + Column: TColumnIndex; const NewText: WideString); + procedure vstGroupsOnEditing(Sender: TBaseVirtualTree; Node: PVirtualNode; + Column: TColumnIndex; var Allowed: Boolean); + protected + FLastX: Integer; + FLastY: Integer; + FAreaMove: TAreaMove; + procedure OnListRegionsPacket(ABuffer: TEnhancedMemoryStream); + private + { private declarations } + public + { public declarations } + end; + +var + frmRegionControl: TfrmRegionControl; + +implementation + +uses + UGameResources, UfrmRadar, UfrmMain, UdmNetwork, UPacket, UPackets, + UGUIPlatformUtils, UAdminHandling, UPacketHandlers; + +type + + { TRequestRegionListPacket } + + TRequestRegionListPacket = class(TPacket) + constructor Create; + end; + + PRegionInfo = ^TRegionInfo; + TRegionInfo = record + Name: string; + Areas: TRectList; + end; + +{ TRequestRegionListPacket } + +constructor TRequestRegionListPacket.Create; +begin + inherited Create($03, 0); + FStream.WriteByte($0A); +end; + +{ TfrmRegionControl } + +procedure TfrmRegionControl.OnListRegionsPacket(ABuffer: TEnhancedMemoryStream); +var + regionCount, areaCount: Byte; + i, j, x1, x2, y1, y2: Integer; + node: PVirtualNode; + regionInfo: PRegionInfo; +begin + vstGroups.BeginUpdate; + vstGroups.Clear; + regionCount := ABuffer.ReadByte; + for i := 0 to regionCount - 1 do + begin + node := vstGroups.AddChild(nil); + regionInfo := vstGroups.GetNodeData(node); + regionInfo^.Name := ABuffer.ReadStringNull; + regionInfo^.Areas := TRectList.Create; + areaCount := ABuffer.ReadByte; + for j := 0 to areaCount - 1 do + begin + x1 := ABuffer.ReadWord; + y1 := ABuffer.ReadWord; + x2 := ABuffer.ReadWord; + y2 := ABuffer.ReadWord; + regionInfo^.Areas.Add(x1, y1, x2, y2); + end; + end; + vstGroups.EndUpdate; +end; + + +procedure TfrmRegionControl.FormCreate(Sender: TObject); +begin + pbArea.Width := frmRadarMap.Radar.Width; + pbArea.Height := frmRadarMap.Radar.Height; + seX1.MaxValue := ResMan.Landscape.CellWidth; + seX2.MaxValue := ResMan.Landscape.CellWidth; + seY1.MaxValue := ResMan.Landscape.CellHeight; + seY2.MaxValue := ResMan.Landscape.CellHeight; + + vstArea.NodeDataSize := SizeOf(TRect); + vstGroups.NodeDataSize := SizeOf(TRegionInfo); + + frmRadarMap.Dependencies.Add(pbArea); + + AdminPacketHandlers[$09] := TPacketHandler.Create(0, @OnListRegionsPacket); +end; + +procedure TfrmRegionControl.btnDeleteAreaClick(Sender: TObject); +var + infoGroup: PRegionInfo; + i: Integer; +begin + if vstGroups.GetFirstSelected <> nil then + begin + infoGroup := vstGroups.GetNodeData(vstGroups.GetFirstSelected); + infoGroup^.Areas.Delete(vstArea.AbsoluteIndex(vstArea.GetFirstSelected)); + vstGroupsChange(vstGroups, vstGroups.GetFirstSelected); + end; +end; + +procedure TfrmRegionControl.btnSaveClick(Sender: TObject); +var + packet: TPacket; + stream: TEnhancedMemoryStream; + groupCount,areaCount: Byte; + i, j: Integer; + node: PVirtualNode; + groupInfo: PRegionInfo; +begin + packet := TPacket.Create($03, 0); + stream := packet.Stream; + stream.Position := stream.Size; + stream.WriteByte($09); + + groupCount := Min(vstGroups.RootNodeCount, 255); + stream.WriteByte(groupCount); + if groupCount = 0 then Exit; + + i := 0; + node := vstGroups.GetFirst; + while (node <> nil) and (i < groupCount) do + begin + groupInfo := vstGroups.GetNodeData(node); + stream.WriteStringNull(groupInfo^.Name); + areaCount:=Min(groupInfo^.Areas.Count,255); + stream.WriteByte(areaCount); + for j := 0 to areaCount-1 do + with groupInfo^.Areas.Rects[j] do + begin + stream.WriteWord(Min(Left, Right)); + stream.WriteWord(Min(Top, Bottom)); + stream.WriteWord(Max(Left, Right)); + stream.WriteWord(Max(Top, Bottom)); + end; + node := vstGroups.GetNext(node); + Inc(i); + end; + dmNetwork.Send(TCompressedPacket.Create(packet)); + Close; +end; + +procedure TfrmRegionControl.acAddGroup(Sender: TObject); +var + node : PVirtualNode; + infoGroup : PRegionInfo; +begin + node := vstGroups.AddChild(nil); + infoGroup := vstGroups.GetNodeData(node); + infoGroup^.Name := 'Unnamed'; + infoGroup^.Areas := TRectList.Create; +end; + +procedure TfrmRegionControl.accRemoveGroup(Sender: TObject); +begin + vstGroups.DeleteSelectedNodes; + vstGroupsChange(vstGroups, nil); +end; + +procedure TfrmRegionControl.btnAddAreaClick(Sender: TObject); +var + node: PVirtualNode; + nodeInfo: ^TRect; + infoGroup : PRegionInfo; +begin + infoGroup:=vstGroups.GetNodeData(vstGroups.GetFirstSelected); + node := vstArea.AddChild(nil); + nodeInfo := vstArea.GetNodeData(node); + nodeInfo^.Left := 0; + nodeInfo^.Top := 0; + nodeInfo^.Right := 0; + nodeInfo^.Bottom := 0; + infoGroup^.Areas.Add(0, 0, 0, 0); + vstArea.ClearSelection; + vstArea.Selected[node] := True; + vstArea.FocusedNode := node; +end; + +procedure TfrmRegionControl.btnClearAreaClick(Sender: TObject); +var + infoGroup: PRegionInfo; + infoArea : TRect; + i: Integer; +begin + if vstGroups.GetFirstSelected <> nil then + begin + infoGroup := vstGroups.GetNodeData(vstGroups.GetFirstSelected); + infoGroup^.Areas.Clear; + vstGroupsChange(vstGroups, vstGroups.GetFirstSelected); + end; +end; + +procedure TfrmRegionControl.btnCloseClick(Sender: TObject); +begin + Close; +end; + +procedure TfrmRegionControl.FormDestroy(Sender: TObject); +begin + frmRadarMap.Dependencies.Remove(pbArea); + if AdminPacketHandlers[$09] <> nil then FreeAndNil(AdminPacketHandlers[$09]); +end; + +procedure TfrmRegionControl.FormShow(Sender: TObject); +begin + SetWindowParent(Handle, frmMain.Handle); + dmNetwork.Send(TRequestRegionListPacket.Create); +end; + +procedure TfrmRegionControl.pbAreaMouseDown(Sender: TObject; + Button: TMouseButton; Shift: TShiftState; X, Y: Integer); +var + node, match: PVirtualNode; + nodeInfo: ^TRect; + p: TPoint; + i: Integer; + infoArea: TRect; + infoGroup: PRegionInfo; +begin + FAreaMove := []; + p := Point(X * 8, Y * 8); + match := nil; + node := vstArea.GetFirst; + while node <> nil do + begin + nodeInfo := vstArea.GetNodeData(node); + if PtInRect(nodeInfo^, p) then + match := node; + node := vstArea.GetNext(node); + end; + if match <> nil then + begin + nodeInfo := vstArea.GetNodeData(match); + if p.x - nodeInfo^.Left <= 64 then Include(FAreaMove, amLeft); + if p.y - nodeInfo^.Top <= 64 then Include(FAreaMove, amTop); + if nodeInfo^.Right - p.x <= 64 then Include(FAreaMove, amRight); + if nodeInfo^.Bottom - p.y <= 64 then Include(FAreaMove, amBottom); + if FAreaMove = [] then + FAreaMove := [amLeft, amTop, amRight, amBottom]; + end else + begin + if vstGroups.GetFirstSelected <> nil then + begin + infoGroup:=vstGroups.GetNodeData(vstGroups.GetFirstSelected); + match := vstArea.AddChild(nil); + nodeInfo:=vstArea.GetNodeData(match); + nodeInfo^.Left := p.x; + nodeInfo^.Top := p.y; + nodeInfo^.Right := p.x; + nodeInfo^.Bottom := p.y; + infoGroup^.Areas.Add(p.x, p.y, p.x, p.y); + + pbArea.Repaint; + + FAreaMove := [amRight, amBottom]; + end; + end; + vstArea.ClearSelection; + vstArea.Selected[match] := True; + FLastX := X; + FLastY := Y; +end; + +procedure TfrmRegionControl.pbAreaMouseMove(Sender: TObject; + Shift: TShiftState; X, Y: Integer); +var + offsetX, offsetY: Integer; +begin + if (ssLeft in Shift) and (vstArea.GetFirstSelected <> nil) then + begin + offsetX := (X - FLastX) * 8; + offsetY := (Y - FLastY) * 8; + if amLeft in FAreaMove then seX1.Value := seX1.Value + offsetX; + if amRight in FAreaMove then seX2.Value := seX2.Value + offsetX; + if amTop in FAreaMove then seY1.Value := seY1.Value + offsetY; + if amBottom in FAreaMove then seY2.Value := seY2.Value + offsetY; + FLastX := X; + FLastY := Y; + seX1Change(nil); + end; +end; + +procedure TfrmRegionControl.pbAreaPaint(Sender: TObject); +var + i: Integer; + node: PVirtualNode; + nodeInfo: ^TRect; +begin + DisplayImage(pbArea.Canvas, 0, 0, frmRadarMap.Radar); + pbArea.Canvas.Pen.Color := clRed; + pbArea.Canvas.Brush.Color := clMaroon; + pbArea.Canvas.Brush.Style := bsFDiagonal; + node := vstArea.GetFirst; + while node <> nil do + begin + if vstArea.Selected[node] then + begin + pbArea.Canvas.Pen.Width := 2; + pbArea.Canvas.Pen.Style := psSolid; + end else + begin + pbArea.Canvas.Pen.Width := 1; + pbArea.Canvas.Pen.Style := psDot; + end; + nodeInfo := vstArea.GetNodeData(node); + pbArea.Canvas.Rectangle(nodeInfo^.Left div 8, nodeInfo^.Top div 8, + nodeInfo^.Right div 8 + 1, nodeInfo^.Bottom div 8 + 1); + node := vstArea.GetNext(node); + end; +end; + +procedure TfrmRegionControl.seX1Change(Sender: TObject); +var + node: PVirtualNode; + nodeInfo: ^TRect; + infoGroup: PRegionInfo; +begin + node := vstArea.GetFirstSelected; + if node <> nil then + begin + nodeInfo := vstArea.GetNodeData(node); + nodeInfo^.Left := seX1.Value; + nodeInfo^.Right := seX2.Value; + nodeInfo^.Top := seY1.Value; + nodeInfo^.Bottom := seY2.Value; + infoGroup:= vstGroups.GetNodeData(vstGroups.GetFirstSelected); + infoGroup^.Areas.Rects[vstArea.AbsoluteIndex(node)] := nodeinfo^; + vstArea.InvalidateNode(node); + pbArea.Repaint; + end; +end; + +procedure TfrmRegionControl.vstAreaChange(Sender: TBaseVirtualTree; + Node: PVirtualNode); +var + nodeInfo: ^TRect; + selected: Boolean; +begin + selected := (Node <> nil) and Sender.Selected[Node]; + btnDeleteArea.Enabled := selected; + lblX.Enabled := selected; + lblY.Enabled := selected; + seX1.Enabled := selected; + seX2.Enabled := selected; + seY1.Enabled := selected; + seY2.Enabled := selected; + if selected then + begin + nodeInfo := Sender.GetNodeData(Node); + seX1.Value := nodeInfo^.Left; + seX2.Value := nodeInfo^.Right; + seY1.Value := nodeInfo^.Top; + seY2.Value := nodeInfo^.Bottom; + end; +end; + +procedure TfrmRegionControl.vstAreaGetText(Sender: TBaseVirtualTree; + Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; + var CellText: WideString); +var + nodeInfo: ^TRect; +begin + nodeInfo := Sender.GetNodeData(Node); + CellText := Format('(%d, %d), (%d, %d)', [nodeInfo^.Left, nodeInfo^.Top, + nodeInfo^.Right, nodeInfo^.Bottom]); +end; + +procedure TfrmRegionControl.vstGroupsChange(Sender: TBaseVirtualTree; + Node: PVirtualNode); +var + i: Integer; + nodeArea: PVirtualNode; + infoGroup: PRegionInfo; + infoArea: ^TRect; + Area: ^TRect; +begin + vstArea.BeginUpdate; + vstArea.Clear; + if Node <> nil then + begin {TODO : code style!!!!} + infoGroup:=Sender.GetNodeData(Node); + for i:=0 to infoGroup^.Areas.Count-1 do + begin + nodeArea := vstArea.AddChild(nil); + infoArea := vstArea.GetNodeData(nodeArea); + Area := infoGroup^.Areas[i]; + infoArea^.Left := Area^.Left; + infoArea^.Top := Area^.Top; + infoArea^.Right := Area^.Right; + infoArea^.Bottom := Area^.Bottom; + end; + end; + vstArea.EndUpdate; + pbArea.Repaint; +end; + +procedure TfrmRegionControl.vstGroupsGetText(Sender: TBaseVirtualTree; + Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; + var CellText: WideString); +var + nodeInfo: PRegionInfo; +begin + nodeInfo := Sender.GetNodeData(Node); + CellText := nodeInfo^.Name; +end; + +procedure TfrmRegionControl.vstGroupsNewText(Sender: TBaseVirtualTree; + Node: PVirtualNode; Column: TColumnIndex; const NewText: WideString); +var + nodeInfo: PRegionInfo; +begin + if (Node <> nil) then begin + nodeInfo := Sender.GetNodeData(Node); + nodeInfo^.Name := NewText; + end; +end; + +procedure TfrmRegionControl.vstGroupsOnEditing(Sender: TBaseVirtualTree; + Node: PVirtualNode; Column: TColumnIndex; var Allowed: Boolean); +begin + Allowed := True; +end; + + +initialization + {$I UfrmRegionControl.lrs} + +end.