diff --git a/Client/Tools/UfrmBoundaries.pas b/Client/Tools/UfrmBoundaries.pas index 65a7cb0..6d7a51f 100644 --- a/Client/Tools/UfrmBoundaries.pas +++ b/Client/Tools/UfrmBoundaries.pas @@ -92,11 +92,13 @@ end; procedure TfrmBoundaries.tbMaxZChange(Sender: TObject); begin seMaxZ.Value := tbMaxZ.Position; + frmMain.InvalidateFilter; end; procedure TfrmBoundaries.tbMinZChange(Sender: TObject); begin seMinZ.Value := tbMinZ.Position; + frmMain.InvalidateFilter; end; procedure TfrmBoundaries.MouseLeave(var msg: TLMessage); diff --git a/Client/Tools/UfrmFilter.lfm b/Client/Tools/UfrmFilter.lfm index 3caf6b1..183af28 100644 --- a/Client/Tools/UfrmFilter.lfm +++ b/Client/Tools/UfrmFilter.lfm @@ -39,6 +39,7 @@ object frmFilter: TfrmFilter 'Exclusive' 'Inclusive' ) + OnClick = rgFilterTypeClick TabOrder = 0 end object GroupBox1: TGroupBox @@ -230,6 +231,7 @@ object frmFilter: TfrmFilter Width = 85 BorderSpacing.Around = 4 Caption = 'Filter active' + OnChange = cbTileFilterChange TabOrder = 1 end end @@ -252,6 +254,7 @@ object frmFilter: TfrmFilter Align = alTop BorderSpacing.Around = 4 Caption = 'Filter active' + OnChange = cbHueFilterChange TabOrder = 0 end object vdtHues: TVirtualDrawTree diff --git a/Client/Tools/UfrmFilter.pas b/Client/Tools/UfrmFilter.pas index f062056..06b249d 100644 --- a/Client/Tools/UfrmFilter.pas +++ b/Client/Tools/UfrmFilter.pas @@ -59,11 +59,14 @@ type vdtHues: TVirtualDrawTree; procedure btnClearClick(Sender: TObject); procedure btnDeleteClick(Sender: TObject); + procedure cbHueFilterChange(Sender: TObject); + procedure cbTileFilterChange(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure FormShow(Sender: TObject); procedure mnuUncheckHuesClick(Sender: TObject); procedure mnuCheckHuesClick(Sender: TObject); + procedure rgFilterTypeClick(Sender: TObject); procedure vdtFilterDragDrop(Sender: TBaseVirtualTree; Source: TObject; DataObject: IDataObject; Formats: TFormatArray; Shift: TShiftState; Pt: TPoint; var Effect: Integer; Mode: TDropMode); @@ -137,6 +140,11 @@ begin end; end; +procedure TfrmFilter.rgFilterTypeClick(Sender: TObject); +begin + frmMain.InvalidateFilter; +end; + procedure TfrmFilter.vdtFilterDragDrop(Sender: TBaseVirtualTree; Source: TObject; DataObject: IDataObject; Formats: TFormatArray; Shift: TShiftState; Pt: TPoint; var Effect: Integer; Mode: TDropMode); @@ -160,6 +168,7 @@ begin targetTileInfo := Sender.GetNodeData(node); targetTileInfo^.ID := sourceTileInfo^.ID; cbTileFilter.Checked := True; + frmMain.InvalidateFilter; end; selected := sourceTree.GetNextSelected(selected); end; @@ -191,6 +200,7 @@ begin hueInfo := Sender.GetNodeData(Node); FCheckedHues.Bits[hueInfo^.ID] := (Sender.CheckState[node] = csCheckedNormal); cbHueFilter.Checked := True; + frmMain.InvalidateFilter; end; procedure TfrmFilter.vdtHuesDrawNode(Sender: TBaseVirtualTree; @@ -321,6 +331,16 @@ begin vdtFilter.DeleteSelectedNodes; end; +procedure TfrmFilter.cbHueFilterChange(Sender: TObject); +begin + frmMain.InvalidateFilter; +end; + +procedure TfrmFilter.cbTileFilterChange(Sender: TObject); +begin + frmMain.InvalidateFilter; +end; + procedure TfrmFilter.btnClearClick(Sender: TObject); begin vdtFilter.Clear; diff --git a/Client/UfrmMain.pas b/Client/UfrmMain.pas index 418a9f3..333f7a9 100644 --- a/Client/UfrmMain.pas +++ b/Client/UfrmMain.pas @@ -42,6 +42,8 @@ type TVirtualTileArray = array of TVirtualTile; TAccessChangedListener = procedure(AAccessLevel: TAccessLevel) of object; + TScreenBufferState = (sbsValid, sbsIndexed, sbsFiltered); + TScreenBufferStates = set of TScreenBufferState; { TfrmMain } @@ -276,8 +278,7 @@ type FLandscape: TLandscape; FTextureManager: TLandTextureManager; FScreenBuffer: TScreenBuffer; - FScreenBufferValid: Boolean; - FScreenBufferIndexed: Boolean; + FScreenBufferState: TScreenBufferStates; FCurrentTile: TWorldItem; FSelectedTile: TWorldItem; FGhostTile: TWorldItem; @@ -312,6 +313,7 @@ type procedure SetY(const AValue: Integer); procedure UpdateCurrentTile; procedure UpdateCurrentTile(AX, AY: Integer); + procedure UpdateFilter; procedure UpdateSelection; procedure WriteChatMessage(ASender, AMessage: string); { Events } @@ -332,6 +334,7 @@ type property CurrentTile: TWorldItem read FCurrentTile write SetCurrentTile; property SelectedTile: TWorldItem read FSelectedTile write SetSelectedTile; { Methods } + procedure InvalidateFilter; procedure RegisterAccessChangedListener(AListener: TAccessChangedListener); procedure SetPos(AX, AY: Word); procedure UnregisterAccessChangedListener(AListener: TAccessChangedListener); @@ -738,7 +741,7 @@ begin FTextureManager := TLandTextureManager.Create; FScreenBuffer := TScreenBuffer.Create; - FScreenBufferValid := False; + FScreenBufferState := []; X := 0; Y := 0; edX.MaxValue := FLandscape.CellWidth; @@ -854,6 +857,7 @@ begin oglGameWindow.Repaint; FLastDraw := Now; end; + Sleep(1); Done := False; end; @@ -932,6 +936,7 @@ begin frmFilter.Locked := False; end else frmFilter.Hide; + InvalidateFilter; end; procedure TfrmMain.acFlatExecute(Sender: TObject); @@ -1675,9 +1680,14 @@ begin glLoadIdentity; end; +procedure TfrmMain.InvalidateFilter; +begin + Exclude(FScreenBufferState, sbsFiltered); +end; + procedure TfrmMain.InvalidateScreenBuffer; begin - FScreenBufferValid := False; + Exclude(FScreenBufferState, sbsValid); end; procedure TfrmMain.PrepareScreenBlock(ABlockInfo: PBlockInfo); @@ -1791,14 +1801,17 @@ var begin tileRect := GetSelectedRect; - if not FScreenBufferValid then + if not (sbsValid in FScreenBufferState) then RebuildScreenBuffer; - if not FScreenBufferIndexed then + if not (sbsIndexed in FScreenBufferState) then begin FScreenBuffer.UpdateShortcuts; - FScreenBufferIndexed := True; + Include(FScreenBufferState, sbsIndexed); end; + + if not (sbsFiltered in FScreenBufferState) then + UpdateFilter; {if acFilter.Checked then staticsFilter := @frmFilter.Filter @@ -2060,7 +2073,7 @@ var cell: TMapCell; begin PrepareScreenBlock(FScreenBuffer.UpdateSortOrder(AMapCell)); - FScreenBufferIndexed := False; + Exclude(FScreenBufferState, sbsIndexed); //Find surrounding cells current := nil; @@ -2102,7 +2115,7 @@ procedure TfrmMain.OnStaticElevated(AStaticItem: TStaticItem); begin AStaticItem.PrioritySolver := FScreenBuffer.GetSerial; PrepareScreenBlock(FScreenBuffer.UpdateSortOrder(AStaticItem)); - FScreenBufferIndexed := False; + Exclude(FScreenBufferState, sbsIndexed); end; procedure TfrmMain.OnStaticHued(AStaticItem: TStaticItem); @@ -2277,8 +2290,7 @@ begin PrepareScreenBlock(blockInfo); FScreenBuffer.UpdateShortcuts; - FScreenBufferValid := True; - FScreenBufferIndexed := True; + FScreenBufferState := [sbsValid, sbsIndexed]; end; procedure TfrmMain.UpdateCurrentTile; @@ -2327,6 +2339,31 @@ begin end; end; +procedure TfrmMain.UpdateFilter; +var + blockInfo: PBlockInfo; +begin + blockInfo := nil; + while FScreenBuffer.Iterate(blockInfo) do + begin + if blockInfo^.State in [ssNormal, ssFiltered] then + begin + blockInfo^.State := ssNormal; + if (blockInfo^.Item.Z < frmBoundaries.tbMinZ.Position) or + (blockInfo^.Item.Z > frmBoundaries.tbMaxZ.Position) then + begin + blockInfo^.State := ssFiltered; + end else + if tbFilter.Down and (blockInfo^.Item is TStaticItem) and + (not frmFilter.Filter(TStaticItem(blockInfo^.Item))) then + begin + blockInfo^.State := ssFiltered; + end; + end; + end; + Include(FScreenBufferState, sbsFiltered); +end; + procedure TfrmMain.UpdateSelection; var selectedRect: TRect;