root / Client / UfrmRegionControl.pas @ 13:c78b5eafa10e
History | View | Annotate | Download (18.2 kB)
| 1 | (*
|
|---|---|
| 2 | * CDDL HEADER START |
| 3 | * |
| 4 | * The contents of this file are subject to the terms of the |
| 5 | * Common Development and Distribution License, Version 1.0 only |
| 6 | * (the "License"). You may not use this file except in compliance |
| 7 | * with the License. |
| 8 | * |
| 9 | * You can obtain a copy of the license at |
| 10 | * http://www.opensource.org/licenses/cddl1.php. |
| 11 | * See the License for the specific language governing permissions |
| 12 | * and limitations under the License. |
| 13 | * |
| 14 | * When distributing Covered Code, include this CDDL HEADER in each |
| 15 | * file and include the License file at |
| 16 | * http://www.opensource.org/licenses/cddl1.php. If applicable, |
| 17 | * add the following below this CDDL HEADER, with the fields enclosed |
| 18 | * by brackets "[]" replaced with your own identifying * information: |
| 19 | * Portions Copyright [yyyy] [name of copyright owner] |
| 20 | * |
| 21 | * CDDL HEADER END |
| 22 | * |
| 23 | * |
| 24 | * Portions Copyright 2008 Andreas Schneider |
| 25 | *) |
| 26 | unit UfrmRegionControl;
|
| 27 | |
| 28 | {$mode objfpc}{$H+} |
| 29 | |
| 30 | interface
|
| 31 | |
| 32 | uses
|
| 33 | Classes, SysUtils, math, LResources, Forms, Controls, Graphics, Dialogs, |
| 34 | VirtualTrees, ExtCtrls, ImagingComponents, StdCtrls, Buttons, Spin, LCLIntf, |
| 35 | UEnhancedMemoryStream, Menus, URectList; |
| 36 | |
| 37 | type
|
| 38 | TAreaMoveType = (amLeft, amTop, amRight, amBottom); |
| 39 | TAreaMove = set of TAreaMoveType; |
| 40 | |
| 41 | { TfrmRegionControl }
|
| 42 | |
| 43 | TfrmRegionControl = class(TForm)
|
| 44 | btnAddArea: TSpeedButton; |
| 45 | btnClearArea: TSpeedButton; |
| 46 | btnDeleteArea: TSpeedButton; |
| 47 | btnClose: TButton; |
| 48 | btnSave: TButton; |
| 49 | Label1: TLabel; |
| 50 | lblX: TLabel; |
| 51 | lblY: TLabel; |
| 52 | mnuAddRegion: TMenuItem; |
| 53 | mnuRemoveRegion: TMenuItem; |
| 54 | Panel1: TPanel; |
| 55 | Panel2: TPanel; |
| 56 | Panel3: TPanel; |
| 57 | pbArea: TPaintBox; |
| 58 | pnlAreaControls: TPanel; |
| 59 | pmRegions: TPopupMenu; |
| 60 | sbArea: TScrollBox; |
| 61 | seX1: TSpinEdit; |
| 62 | seX2: TSpinEdit; |
| 63 | seY1: TSpinEdit; |
| 64 | seY2: TSpinEdit; |
| 65 | vstRegions: TVirtualStringTree; |
| 66 | vstArea: TVirtualStringTree; |
| 67 | procedure mnuAddRegionClick(Sender: TObject);
|
| 68 | procedure mnuRemoveRegionClick(Sender: TObject);
|
| 69 | procedure btnAddAreaClick(Sender: TObject);
|
| 70 | procedure btnClearAreaClick(Sender: TObject);
|
| 71 | procedure btnCloseClick(Sender: TObject);
|
| 72 | procedure btnDeleteAreaClick(Sender: TObject);
|
| 73 | procedure btnSaveClick(Sender: TObject);
|
| 74 | procedure FormCreate(Sender: TObject);
|
| 75 | procedure FormDestroy(Sender: TObject);
|
| 76 | procedure FormShow(Sender: TObject);
|
| 77 | procedure pbAreaMouseDown(Sender: TObject; Button: TMouseButton;
|
| 78 | Shift: TShiftState; X, Y: Integer); |
| 79 | procedure pbAreaMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer
|
| 80 | ); |
| 81 | procedure pbAreaPaint(Sender: TObject);
|
| 82 | procedure seX1Change(Sender: TObject);
|
| 83 | procedure vstAreaChange(Sender: TBaseVirtualTree; Node: PVirtualNode);
|
| 84 | procedure vstAreaGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
| 85 | Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
|
| 86 | procedure vstRegionsChange(Sender: TBaseVirtualTree; Node: PVirtualNode);
|
| 87 | procedure vstRegionsFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
|
| 88 | procedure vstRegionsGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
| 89 | Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
|
| 90 | protected
|
| 91 | FLastX: Integer; |
| 92 | FLastY: Integer; |
| 93 | FAreaMove: TAreaMove; |
| 94 | function FindRegion(AName: string): PVirtualNode; |
| 95 | procedure OnModifyRegionPacket(ABuffer: TEnhancedMemoryStream);
|
| 96 | procedure OnDeleteRegionPacket(ABuffer: TEnhancedMemoryStream);
|
| 97 | procedure OnListRegionsPacket(ABuffer: TEnhancedMemoryStream);
|
| 98 | private
|
| 99 | { private declarations }
|
| 100 | public
|
| 101 | { public declarations }
|
| 102 | end;
|
| 103 | |
| 104 | var
|
| 105 | frmRegionControl: TfrmRegionControl; |
| 106 | |
| 107 | implementation
|
| 108 | |
| 109 | uses
|
| 110 | UGameResources, UfrmRadar, UfrmMain, UdmNetwork, UPacket, UGUIPlatformUtils, |
| 111 | UAdminHandling, UPacketHandlers; |
| 112 | |
| 113 | type
|
| 114 | |
| 115 | PRegionInfo = ^TRegionInfo; |
| 116 | TRegionInfo = record
|
| 117 | Name: string;
|
| 118 | Areas: TRectList; |
| 119 | end;
|
| 120 | |
| 121 | { TModifyRegionPacket }
|
| 122 | |
| 123 | TModifyRegionPacket = class(TPacket)
|
| 124 | constructor Create(ARegionInfo: TRegionInfo);
|
| 125 | end;
|
| 126 | |
| 127 | { TDeleteRegionPacket }
|
| 128 | |
| 129 | TDeleteRegionPacket = class(TPacket)
|
| 130 | constructor Create(AName: string); |
| 131 | end;
|
| 132 | |
| 133 | { TRequestRegionListPacket }
|
| 134 | |
| 135 | TRequestRegionListPacket = class(TPacket)
|
| 136 | constructor Create;
|
| 137 | end;
|
| 138 | |
| 139 | { TModifyRegionPacket }
|
| 140 | |
| 141 | constructor TModifyRegionPacket.Create(ARegionInfo: TRegionInfo);
|
| 142 | var
|
| 143 | i: Integer; |
| 144 | count: Byte; |
| 145 | area: TRect; |
| 146 | begin
|
| 147 | inherited Create($03, 0); //Admin Packet |
| 148 | FStream.WriteByte($08); //Admin PacketID |
| 149 | FStream.WriteStringNull(ARegionInfo.Name); |
| 150 | count := Min(ARegionInfo.Areas.Count, 256);
|
| 151 | FStream.WriteByte(count); |
| 152 | for i := 0 to count - 1 do |
| 153 | begin
|
| 154 | area := ARegionInfo.Areas.Rects[i]; |
| 155 | FStream.WriteWord(area.Left); |
| 156 | FStream.WriteWord(area.Top); |
| 157 | FStream.WriteWord(area.Right); |
| 158 | FStream.WriteWord(area.Bottom); |
| 159 | end;
|
| 160 | end;
|
| 161 | |
| 162 | { TDeleteRegionPacket }
|
| 163 | |
| 164 | constructor TDeleteRegionPacket.Create(AName: string); |
| 165 | begin
|
| 166 | inherited Create($03, 0); //Admin Packet |
| 167 | FStream.WriteByte($09); //Admin PacketID |
| 168 | FStream.WriteStringNull(AName); |
| 169 | end;
|
| 170 | |
| 171 | { TRequestRegionListPacket }
|
| 172 | |
| 173 | constructor TRequestRegionListPacket.Create;
|
| 174 | begin
|
| 175 | inherited Create($03, 0); //Admin Packet |
| 176 | FStream.WriteByte($0A); //Admin PacketID |
| 177 | end;
|
| 178 | |
| 179 | { TfrmRegionControl }
|
| 180 | |
| 181 | procedure TfrmRegionControl.FormCreate(Sender: TObject);
|
| 182 | begin
|
| 183 | pbArea.Width := frmRadarMap.Radar.Width; |
| 184 | pbArea.Height := frmRadarMap.Radar.Height; |
| 185 | seX1.MaxValue := ResMan.Landscape.CellWidth; |
| 186 | seX2.MaxValue := ResMan.Landscape.CellWidth; |
| 187 | seY1.MaxValue := ResMan.Landscape.CellHeight; |
| 188 | seY2.MaxValue := ResMan.Landscape.CellHeight; |
| 189 | |
| 190 | vstArea.NodeDataSize := SizeOf(TRect); |
| 191 | vstRegions.NodeDataSize := SizeOf(TRegionInfo); |
| 192 | |
| 193 | frmRadarMap.Dependencies.Add(pbArea); |
| 194 | |
| 195 | AssignAdminPacketHandler($08, TPacketHandler.Create(0, @OnModifyRegionPacket)); |
| 196 | AssignAdminPacketHandler($09, TPacketHandler.Create(0, @OnDeleteRegionPacket)); |
| 197 | AssignAdminPacketHandler($0A, TPacketHandler.Create(0, @OnListRegionsPacket)); |
| 198 | end;
|
| 199 | |
| 200 | procedure TfrmRegionControl.FormDestroy(Sender: TObject);
|
| 201 | begin
|
| 202 | frmRadarMap.Dependencies.Remove(pbArea); |
| 203 | if AdminPacketHandlers[$08] <> nil then FreeAndNil(AdminPacketHandlers[$08]); |
| 204 | if AdminPacketHandlers[$09] <> nil then FreeAndNil(AdminPacketHandlers[$09]); |
| 205 | if AdminPacketHandlers[$0A] <> nil then FreeAndNil(AdminPacketHandlers[$0A]); |
| 206 | end;
|
| 207 | |
| 208 | procedure TfrmRegionControl.FormShow(Sender: TObject);
|
| 209 | begin
|
| 210 | SetWindowParent(Handle, frmMain.Handle); |
| 211 | btnSave.Enabled := False; //no changes yet
|
| 212 | dmNetwork.Send(TRequestRegionListPacket.Create); |
| 213 | end;
|
| 214 | |
| 215 | procedure TfrmRegionControl.btnSaveClick(Sender: TObject);
|
| 216 | var
|
| 217 | regionNode: PVirtualNode; |
| 218 | regionInfo: PRegionInfo; |
| 219 | areaNode: PVirtualNode; |
| 220 | areaInfo: PRect; |
| 221 | begin
|
| 222 | btnSave.Enabled := False; |
| 223 | |
| 224 | //Refresh the current region
|
| 225 | regionNode := vstRegions.GetFirstSelected; |
| 226 | if regionNode <> nil then |
| 227 | begin
|
| 228 | regionInfo := vstRegions.GetNodeData(regionNode); |
| 229 | regionInfo^.Areas.Clear; |
| 230 | areaNode := vstArea.GetFirst; |
| 231 | while areaNode <> nil do |
| 232 | begin
|
| 233 | areaInfo := vstArea.GetNodeData(areaNode); |
| 234 | regionInfo^.Areas.Add(areaInfo^.Left, areaInfo^.Top, areaInfo^.Right, |
| 235 | areaInfo^.Bottom); |
| 236 | areaNode := vstArea.GetNext(areaNode); |
| 237 | end;
|
| 238 | |
| 239 | //Send the modified values
|
| 240 | dmNetwork.Send(TModifyRegionPacket.Create(regionInfo^)); |
| 241 | end;
|
| 242 | |
| 243 | //Clear the selection
|
| 244 | vstRegions.ClearSelection; |
| 245 | end;
|
| 246 | |
| 247 | procedure TfrmRegionControl.mnuAddRegionClick(Sender: TObject);
|
| 248 | var
|
| 249 | regionName: string;
|
| 250 | node: PVirtualNode; |
| 251 | regionInfo: PRegionInfo; |
| 252 | begin
|
| 253 | regionName := '';
|
| 254 | if InputQuery('New Region', 'Enter the name for the new region:', regionName) then |
| 255 | begin
|
| 256 | if FindRegion(regionName) = nil then |
| 257 | begin
|
| 258 | node := vstRegions.AddChild(nil);
|
| 259 | regionInfo := vstRegions.GetNodeData(node); |
| 260 | regionInfo^.Name := regionName; |
| 261 | regionInfo^.Areas := TRectList.Create; |
| 262 | vstRegions.ClearSelection; |
| 263 | vstRegions.Selected[node] := True; |
| 264 | btnSave.Enabled := True; |
| 265 | end else |
| 266 | begin
|
| 267 | MessageDlg('New Region', 'The region could not be added. A region with ' + |
| 268 | 'that name already exists.', mtError, [mbOK], 0); |
| 269 | end;
|
| 270 | end;
|
| 271 | end;
|
| 272 | |
| 273 | procedure TfrmRegionControl.mnuRemoveRegionClick(Sender: TObject);
|
| 274 | var
|
| 275 | regionNode: PVirtualNode; |
| 276 | regionInfo: PRegionInfo; |
| 277 | begin
|
| 278 | regionNode := vstRegions.GetFirstSelected; |
| 279 | if (regionNode <> nil) and (MessageDlg('Delete Region', 'Are you sure, you ' + |
| 280 | 'want to delete the selected region?', mtConfirmation, [mbYes, mbNo], 0) = mrYes) then |
| 281 | begin
|
| 282 | regionInfo := vstRegions.GetNodeData(regionNode); |
| 283 | dmNetwork.Send(TDeleteRegionPacket.Create(regionInfo^.Name)); |
| 284 | vstRegions.Selected[regionNode] := False; |
| 285 | end;
|
| 286 | end;
|
| 287 | |
| 288 | procedure TfrmRegionControl.btnAddAreaClick(Sender: TObject);
|
| 289 | var
|
| 290 | node: PVirtualNode; |
| 291 | areaInfo: PRect; |
| 292 | begin
|
| 293 | node := vstArea.AddChild(nil);
|
| 294 | areaInfo := vstArea.GetNodeData(node); |
| 295 | areaInfo^.Left := 0;
|
| 296 | areaInfo^.Top := 0;
|
| 297 | areaInfo^.Right := 0;
|
| 298 | areaInfo^.Bottom := 0;
|
| 299 | vstArea.ClearSelection; |
| 300 | vstArea.Selected[node] := True; |
| 301 | vstArea.FocusedNode := node; |
| 302 | |
| 303 | btnSave.Enabled := True; //possible change to be saved
|
| 304 | end;
|
| 305 | |
| 306 | procedure TfrmRegionControl.btnClearAreaClick(Sender: TObject);
|
| 307 | begin
|
| 308 | vstArea.Clear; |
| 309 | vstAreaChange(vstArea, nil);
|
| 310 | end;
|
| 311 | |
| 312 | procedure TfrmRegionControl.btnCloseClick(Sender: TObject);
|
| 313 | begin
|
| 314 | if btnSave.Enabled and (MessageDlg('Unsaved changes', 'There are unsaved ' + |
| 315 | 'changes.' + #13#10+#13#10+ 'Do you want to save them now?', |
| 316 | mtConfirmation, [mbYes, mbNo], 0) = mrYes) then |
| 317 | begin
|
| 318 | btnSaveClick(Sender); |
| 319 | end;
|
| 320 | |
| 321 | Close; |
| 322 | end;
|
| 323 | |
| 324 | procedure TfrmRegionControl.btnDeleteAreaClick(Sender: TObject);
|
| 325 | begin
|
| 326 | vstArea.DeleteSelectedNodes; |
| 327 | vstAreaChange(vstArea, nil);
|
| 328 | |
| 329 | btnSave.Enabled := True; //possible change to be saved
|
| 330 | end;
|
| 331 | |
| 332 | procedure TfrmRegionControl.pbAreaMouseDown(Sender: TObject;
|
| 333 | Button: TMouseButton; Shift: TShiftState; X, Y: Integer); |
| 334 | var
|
| 335 | areaNode, match: PVirtualNode; |
| 336 | areaInfo: PRect; |
| 337 | p: TPoint; |
| 338 | begin
|
| 339 | FAreaMove := []; |
| 340 | p := Point(X * 8, Y * 8); |
| 341 | match := nil;
|
| 342 | areaNode := vstArea.GetFirst; |
| 343 | while areaNode <> nil do //find the last matching area |
| 344 | begin
|
| 345 | areaInfo := vstArea.GetNodeData(areaNode); |
| 346 | if PtInRect(areaInfo^, p) then |
| 347 | match := areaNode; |
| 348 | areaNode := vstArea.GetNext(areaNode); |
| 349 | end;
|
| 350 | if match <> nil then |
| 351 | begin
|
| 352 | areaInfo := vstArea.GetNodeData(match); |
| 353 | if p.x - areaInfo^.Left <= 64 then Include(FAreaMove, amLeft); |
| 354 | if p.y - areaInfo^.Top <= 64 then Include(FAreaMove, amTop); |
| 355 | if areaInfo^.Right - p.x <= 64 then Include(FAreaMove, amRight); |
| 356 | if areaInfo^.Bottom - p.y <= 64 then Include(FAreaMove, amBottom); |
| 357 | if FAreaMove = [] then |
| 358 | FAreaMove := [amLeft, amTop, amRight, amBottom]; |
| 359 | end else |
| 360 | begin
|
| 361 | match := vstArea.AddChild(nil);
|
| 362 | areaInfo := vstArea.GetNodeData(match); |
| 363 | areaInfo^.Left := p.x; |
| 364 | areaInfo^.Top := p.y; |
| 365 | areaInfo^.Right := p.x; |
| 366 | areaInfo^.Bottom := p.y; |
| 367 | pbArea.Repaint; |
| 368 | FAreaMove := [amRight, amBottom]; |
| 369 | end;
|
| 370 | vstArea.ClearSelection; |
| 371 | vstArea.Selected[match] := True; |
| 372 | FLastX := X; |
| 373 | FLastY := Y; |
| 374 | end;
|
| 375 | |
| 376 | procedure TfrmRegionControl.pbAreaMouseMove(Sender: TObject;
|
| 377 | Shift: TShiftState; X, Y: Integer); |
| 378 | var
|
| 379 | offsetX, offsetY: Integer; |
| 380 | begin
|
| 381 | if (ssLeft in Shift) and (vstArea.GetFirstSelected <> nil) then |
| 382 | begin
|
| 383 | offsetX := (X - FLastX) * 8;
|
| 384 | offsetY := (Y - FLastY) * 8;
|
| 385 | if amLeft in FAreaMove then seX1.Value := seX1.Value + offsetX; |
| 386 | if amRight in FAreaMove then seX2.Value := seX2.Value + offsetX; |
| 387 | if amTop in FAreaMove then seY1.Value := seY1.Value + offsetY; |
| 388 | if amBottom in FAreaMove then seY2.Value := seY2.Value + offsetY; |
| 389 | FLastX := X; |
| 390 | FLastY := Y; |
| 391 | seX1Change(nil);
|
| 392 | end;
|
| 393 | end;
|
| 394 | |
| 395 | procedure TfrmRegionControl.pbAreaPaint(Sender: TObject);
|
| 396 | var
|
| 397 | node: PVirtualNode; |
| 398 | areaInfo: PRect; |
| 399 | begin
|
| 400 | DisplayImage(pbArea.Canvas, 0, 0, frmRadarMap.Radar); |
| 401 | pbArea.Canvas.Pen.Color := clRed; |
| 402 | pbArea.Canvas.Brush.Color := clMaroon; |
| 403 | pbArea.Canvas.Brush.Style := bsFDiagonal; |
| 404 | node := vstArea.GetFirst; |
| 405 | while node <> nil do |
| 406 | begin
|
| 407 | if vstArea.Selected[node] then |
| 408 | begin
|
| 409 | pbArea.Canvas.Pen.Width := 2;
|
| 410 | pbArea.Canvas.Pen.Style := psSolid; |
| 411 | end else |
| 412 | begin
|
| 413 | pbArea.Canvas.Pen.Width := 1;
|
| 414 | pbArea.Canvas.Pen.Style := psDot; |
| 415 | end;
|
| 416 | areaInfo := vstArea.GetNodeData(node); |
| 417 | pbArea.Canvas.Rectangle(areaInfo^.Left div 8, areaInfo^.Top div 8, |
| 418 | areaInfo^.Right div 8 + 1, areaInfo^.Bottom div 8 + 1); |
| 419 | node := vstArea.GetNext(node); |
| 420 | end;
|
| 421 | end;
|
| 422 | |
| 423 | procedure TfrmRegionControl.seX1Change(Sender: TObject);
|
| 424 | var
|
| 425 | node: PVirtualNode; |
| 426 | areaInfo: PRect; |
| 427 | begin
|
| 428 | node := vstArea.GetFirstSelected; |
| 429 | if node <> nil then |
| 430 | begin
|
| 431 | areaInfo := vstArea.GetNodeData(node); |
| 432 | areaInfo^.Left := seX1.Value; |
| 433 | areaInfo^.Right := seX2.Value; |
| 434 | areaInfo^.Top := seY1.Value; |
| 435 | areaInfo^.Bottom := seY2.Value; |
| 436 | vstArea.InvalidateNode(node); |
| 437 | pbArea.Repaint; |
| 438 | |
| 439 | btnSave.Enabled := True; //possible change to be saved
|
| 440 | end;
|
| 441 | end;
|
| 442 | |
| 443 | procedure TfrmRegionControl.vstAreaChange(Sender: TBaseVirtualTree;
|
| 444 | Node: PVirtualNode); |
| 445 | var
|
| 446 | areaInfo: PRect; |
| 447 | selected: Boolean; |
| 448 | begin
|
| 449 | selected := (Node <> nil) and Sender.Selected[Node]; |
| 450 | btnDeleteArea.Enabled := selected; |
| 451 | lblX.Enabled := selected; |
| 452 | lblY.Enabled := selected; |
| 453 | seX1.Enabled := selected; |
| 454 | seX2.Enabled := selected; |
| 455 | seY1.Enabled := selected; |
| 456 | seY2.Enabled := selected; |
| 457 | if selected then |
| 458 | begin
|
| 459 | areaInfo := Sender.GetNodeData(Node); |
| 460 | seX1.Value := areaInfo^.Left; |
| 461 | seX2.Value := areaInfo^.Right; |
| 462 | seY1.Value := areaInfo^.Top; |
| 463 | seY2.Value := areaInfo^.Bottom; |
| 464 | end;
|
| 465 | pbArea.Repaint; |
| 466 | end;
|
| 467 | |
| 468 | procedure TfrmRegionControl.vstAreaGetText(Sender: TBaseVirtualTree;
|
| 469 | Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; |
| 470 | var CellText: WideString);
|
| 471 | var
|
| 472 | areaInfo: PRect; |
| 473 | begin
|
| 474 | areaInfo := Sender.GetNodeData(Node); |
| 475 | CellText := Format('(%d, %d), (%d, %d)', [areaInfo^.Left, areaInfo^.Top,
|
| 476 | areaInfo^.Right, areaInfo^.Bottom]); |
| 477 | end;
|
| 478 | |
| 479 | procedure TfrmRegionControl.vstRegionsChange(Sender: TBaseVirtualTree;
|
| 480 | Node: PVirtualNode); |
| 481 | var
|
| 482 | i: Integer; |
| 483 | selected, areaNode: PVirtualNode; |
| 484 | regionInfo: PRegionInfo; |
| 485 | areaInfo: PRect; |
| 486 | begin
|
| 487 | if btnSave.Enabled and (MessageDlg('Unsaved changes', 'There are unsaved ' + |
| 488 | 'changes.' + #13#10+#13#10+ 'Do you want to save them now?', |
| 489 | mtConfirmation, [mbYes, mbNo], 0) = mrYes) then |
| 490 | begin
|
| 491 | btnSaveClick(Sender); |
| 492 | end;
|
| 493 | |
| 494 | vstArea.BeginUpdate; |
| 495 | vstArea.Clear; |
| 496 | selected := Sender.GetFirstSelected; |
| 497 | if selected <> nil then |
| 498 | begin
|
| 499 | btnAddArea.Enabled := True; |
| 500 | btnClearArea.Enabled := True; |
| 501 | mnuRemoveRegion.Enabled := True; |
| 502 | |
| 503 | regionInfo := Sender.GetNodeData(selected); |
| 504 | for i := 0 to regionInfo^.Areas.Count - 1 do |
| 505 | begin
|
| 506 | areaNode := vstArea.AddChild(nil);
|
| 507 | areaInfo := vstArea.GetNodeData(areaNode); |
| 508 | with regionInfo^.Areas.Rects[i] do |
| 509 | begin
|
| 510 | areaInfo^.Left := Left; |
| 511 | areaInfo^.Top := Top; |
| 512 | areaInfo^.Right := Right; |
| 513 | areaInfo^.Bottom := Bottom; |
| 514 | end;
|
| 515 | end;
|
| 516 | end else |
| 517 | begin
|
| 518 | btnAddArea.Enabled := False; |
| 519 | btnDeleteArea.Enabled := False; |
| 520 | btnClearArea.Enabled := False; |
| 521 | mnuRemoveRegion.Enabled := False; |
| 522 | end;
|
| 523 | vstArea.EndUpdate; |
| 524 | pbArea.Repaint; |
| 525 | |
| 526 | btnSave.Enabled := False; //no changes to be saved
|
| 527 | end;
|
| 528 | |
| 529 | procedure TfrmRegionControl.vstRegionsFreeNode(Sender: TBaseVirtualTree;
|
| 530 | Node: PVirtualNode); |
| 531 | var
|
| 532 | regionInfo: PRegionInfo; |
| 533 | begin
|
| 534 | regionInfo := Sender.GetNodeData(Node); |
| 535 | if regionInfo^.Areas <> nil then FreeAndNil(regionInfo^.Areas); |
| 536 | end;
|
| 537 | |
| 538 | procedure TfrmRegionControl.vstRegionsGetText(Sender: TBaseVirtualTree;
|
| 539 | Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; |
| 540 | var CellText: WideString);
|
| 541 | var
|
| 542 | regionInfo: PRegionInfo; |
| 543 | begin
|
| 544 | regionInfo := Sender.GetNodeData(Node); |
| 545 | CellText := regionInfo^.Name; |
| 546 | end;
|
| 547 | |
| 548 | function TfrmRegionControl.FindRegion(AName: string): PVirtualNode; |
| 549 | var
|
| 550 | regionInfo: PRegionInfo; |
| 551 | found: Boolean; |
| 552 | begin
|
| 553 | found := False; |
| 554 | Result := vstRegions.GetFirst; |
| 555 | while (Result <> nil) and (not found) do |
| 556 | begin
|
| 557 | regionInfo := vstRegions.GetNodeData(Result); |
| 558 | if regionInfo^.Name = AName then |
| 559 | found := True |
| 560 | else
|
| 561 | Result := vstRegions.GetNext(Result); |
| 562 | end;
|
| 563 | end;
|
| 564 | |
| 565 | procedure TfrmRegionControl.OnModifyRegionPacket(ABuffer: TEnhancedMemoryStream);
|
| 566 | var
|
| 567 | regionName: string;
|
| 568 | regionNode: PVirtualNode; |
| 569 | regionInfo: PRegionInfo; |
| 570 | areaCount: Byte; |
| 571 | i: Integer; |
| 572 | x1, y1, x2, y2: Word; |
| 573 | begin
|
| 574 | ABuffer.ReadByte; //status, not used yet
|
| 575 | |
| 576 | //TODO : Ask user how to proceed, if the added/modified packet conflicts with the currently edited region
|
| 577 | |
| 578 | regionName := ABuffer.ReadStringNull; |
| 579 | regionNode := FindRegion(regionName); |
| 580 | if regionNode = nil then |
| 581 | begin
|
| 582 | regionNode := vstRegions.AddChild(nil);
|
| 583 | regionInfo := vstRegions.GetNodeData(regionNode); |
| 584 | regionInfo^.Name := regionName; |
| 585 | regionInfo^.Areas := TRectList.Create; |
| 586 | end else |
| 587 | begin
|
| 588 | regionInfo := vstRegions.GetNodeData(regionNode); |
| 589 | regionInfo^.Areas.Clear; |
| 590 | end;
|
| 591 | |
| 592 | areaCount := ABuffer.ReadByte; |
| 593 | for i := 0 to areaCount - 1 do |
| 594 | begin
|
| 595 | x1 := ABuffer.ReadWord; |
| 596 | y1 := ABuffer.ReadWord; |
| 597 | x2 := ABuffer.ReadWord; |
| 598 | y2 := ABuffer.ReadWord; |
| 599 | regionInfo^.Areas.Add(x1, y1, x2, y2); |
| 600 | end;
|
| 601 | |
| 602 | if vstRegions.Selected[regionNode] then |
| 603 | begin
|
| 604 | btnSave.Enabled := False; |
| 605 | vstRegionsChange(vstRegions, regionNode); |
| 606 | end;
|
| 607 | end;
|
| 608 | |
| 609 | procedure TfrmRegionControl.OnDeleteRegionPacket(ABuffer: TEnhancedMemoryStream);
|
| 610 | var
|
| 611 | regionName: string;
|
| 612 | regionNode: PVirtualNode; |
| 613 | begin
|
| 614 | ABuffer.ReadByte; //status, not used yet
|
| 615 | regionName := ABuffer.ReadStringNull; |
| 616 | regionNode := FindRegion(regionName); |
| 617 | |
| 618 | //TODO : Ask user how to proceed, if the deleted packet conflicts with the currently edited region
|
| 619 | |
| 620 | if regionNode <> nil then |
| 621 | vstRegions.DeleteNode(regionNode); |
| 622 | end;
|
| 623 | |
| 624 | procedure TfrmRegionControl.OnListRegionsPacket(ABuffer: TEnhancedMemoryStream);
|
| 625 | var
|
| 626 | regionCount, areaCount: Byte; |
| 627 | i, j, x1, x2, y1, y2: Integer; |
| 628 | node: PVirtualNode; |
| 629 | regionInfo: PRegionInfo; |
| 630 | begin
|
| 631 | vstRegions.BeginUpdate; |
| 632 | vstRegions.Clear; |
| 633 | regionCount := ABuffer.ReadByte; |
| 634 | for i := 0 to regionCount - 1 do |
| 635 | begin
|
| 636 | node := vstRegions.AddChild(nil);
|
| 637 | regionInfo := vstRegions.GetNodeData(node); |
| 638 | regionInfo^.Name := ABuffer.ReadStringNull; |
| 639 | regionInfo^.Areas := TRectList.Create; |
| 640 | areaCount := ABuffer.ReadByte; |
| 641 | for j := 0 to areaCount - 1 do |
| 642 | begin
|
| 643 | x1 := ABuffer.ReadWord; |
| 644 | y1 := ABuffer.ReadWord; |
| 645 | x2 := ABuffer.ReadWord; |
| 646 | y2 := ABuffer.ReadWord; |
| 647 | regionInfo^.Areas.Add(x1, y1, x2, y2); |
| 648 | end;
|
| 649 | end;
|
| 650 | vstRegions.EndUpdate; |
| 651 | end;
|
| 652 | |
| 653 | initialization
|
| 654 | {$I UfrmRegionControl.lrs}
|
| 655 | |
| 656 | end.
|