unit MetaEditor; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, _BaseTemplate, ExtCtrls, VirtualTrees, StdCtrls, ComCtrls, Grids, MPHexEditor, Wrapgrid, VTHeaderPopup, Menus, _TreeElement; type TForm_Meta = class(TForm_BaseTemplate) VST: TVirtualStringTree; splitter: TSplitter; rightPages: TPageControl; tab_hex: TTabSheet; tab_meta: TTabSheet; panel_hex_actions: TPanel; hex: TMPHexEditor; splitter_hex_1: TSplitter; value_viewer: TWrapGrid; splitter_hex_2: TSplitter; structviewer: TVirtualStringTree; value_viewer_context: TPopupMenu; value_viewer_context_copy: TMenuItem; value_viewer_context_copyasdec: TMenuItem; value_viewer_context_copyasfloat: TMenuItem; value_viewer_context_copyasbitset: TMenuItem; value_viewer_context_copyasstring: TMenuItem; value_viewer_context_copyashex: TMenuItem; VTHPopup: TVTHeaderPopupMenu; btn_export: TButton; btn_import: TButton; vst_popup: TPopupMenu; vst_newRoot: TMenuItem; vst_setRoot: TMenuItem; procedure FormCreate(Sender: TObject); procedure VSTInitChildren(Sender: TBaseVirtualTree; Node: PVirtualNode; var ChildCount: Cardinal); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure VSTFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex); procedure VSTFocusChanging(Sender: TBaseVirtualTree; OldNode, NewNode: PVirtualNode; OldColumn, NewColumn: TColumnIndex; var Allowed: Boolean); procedure VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString); procedure VSTPaintText(Sender: TBaseVirtualTree; const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType); procedure VSTGetPopupMenu(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; const P: TPoint; var AskParent: Boolean; var PopupMenu: TPopupMenu); procedure vst_setRootClick(Sender: TObject); procedure vst_newRootClick(Sender: TObject); procedure VSTGetHint(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; var LineBreakStyle: TVTTooltipLineBreakStyle; var HintText: WideString); private root: TTreeElement; procedure NewCon(ID: Integer); public procedure SetRoot(TreeElem: TTreeElement); end; implementation {$R *.dfm} uses _MetaManager, _MetaTypes, ConnectionManager, Data, _FileTypes, Main, TypeDefs; type PNodeData = ^TNodeData; TNodeData = record Field: TTreeElement; end; function AddVSTEntry(AVST: TCustomVirtualStringTree; ANode: PVirtualNode; ARecord: TNodeData): PVirtualNode; var Data: PNodeData; begin Result := AVST.AddChild(ANode); Data := AVST.GetNodeData(Result); AVST.ValidateNode(Result, False); Data^ := ARecord; end; procedure TForm_Meta.NewCon(ID: Integer); begin if ID >= 0 then SetRoot(ConManager.Connection[FConnectionID].MetaData.Root); //SetRoot(ConManager.Connection[FConnectionID].MetaData.FileById[454]); end; procedure TForm_Meta.SetRoot(TreeElem: TTreeElement); var i: Integer; data: TNodeData; node: PVirtualNode; basenode: PVirtualNode; begin if FConnectionID <> TreeElem.ConnectionID then SelectConnection(TreeElem.ConnectionID); root := TreeElem; VST.Clear; VST.BeginUpdate; data.Field := root; basenode := AddVSTEntry(VST, nil, data); for i := 0 to root.ChildCount - 1 do begin data.Field := root.Child[i]; node := AddVSTEntry(VST, basenode, data); if data.Field.ChildCount > 0 then VST.HasChildren[node] := True; end; VST.EndUpdate; end; procedure TForm_Meta.VSTInitChildren(Sender: TBaseVirtualTree; Node: PVirtualNode; var ChildCount: Cardinal); var data: PNodeData; newdata: TNodeData; newnode: PVirtualNode; i: Integer; begin data := Sender.GetNodeData(node); if data.Field.ChildCount > 0 then begin for i := 0 to data.Field.ChildCount - 1 do begin newdata.Field := data.Field.Child[i]; newnode := AddVSTEntry(TCustomVirtualStringTree(Sender), Node, newdata); if newdata.Field.ChildCount > 0 then Sender.HasChildren[newnode] := True; end; end; ChildCount := Sender.ChildCount[Node]; end; procedure TForm_Meta.VSTFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex); var data: PNodeData; ffile: TResource; //******************************************************************* fs: TFileStream; //******************************************************************* begin data := Sender.GetNodeData(Node); ffile := nil; if data.Field is TResource then ffile := TResource(data.Field); if data.Field is _MetaTypes.TDatLink then if Assigned(_MetaTypes.TDatLink(data.Field).TargetFile) then ffile := TResource(_MetaTypes.TDatLink(data.Field).TargetFile); if Assigned(ffile) then begin if Assigned(ffile.Editor) then begin ffile.Editor.Align := alClient; tab_meta.InsertControl(ffile.Editor); ffile.Opened := True; end; //******************************************************************* // fs := TFileStream.Create('C:\Spiele\Oni\GameDataFolder\tests\'+IntToStr(ffile.FileInfo.ID)+'_recreated.hex', fmCreate); // ffile.ReCreateFile(fs); // fs.Free; //******************************************************************* end; end; procedure TForm_Meta.VSTFocusChanging(Sender: TBaseVirtualTree; OldNode, NewNode: PVirtualNode; OldColumn, NewColumn: TColumnIndex; var Allowed: Boolean); var data: PNodeData; i: Integer; begin data := Sender.GetNodeData(NewNode); if data.Field is TResource then begin if Assigned(TResource(data.Field).Editor) then Allowed := not TResource(data.Field).Opened else Allowed := True; end; if Allowed and Assigned(OldNode) then begin data := Sender.GetNodeData(OldNode); if data.Field is TResource then begin if TResource(data.Field).Opened then begin if tab_meta.ControlCount > 0 then for i := 0 to tab_meta.ControlCount - 1 do tab_meta.RemoveControl(tab_meta.Controls[i]); TResource(data.Field).Opened := False; end; end; end; end; procedure TForm_Meta.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString); var Data: PNodeData; begin Data := Sender.GetNodeData(Node); CellText := ''; if TextType = ttNormal then begin case Column of 0: CellText := Data.Field.Caption; 1: CellText := data.Field.VType; 2: begin if Data.Field is TDataField then CellText := TDataField(Data.Field).ValueAsString; end; end; end; end; procedure TForm_Meta.VSTPaintText(Sender: TBaseVirtualTree; const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType); var Data: PNodeData; begin Data := Sender.GetNodeData(Node); if TextType = ttNormal then begin case Column of 0: begin if Data.Field is TResource then begin if Length(TResource(Data.Field).FileInfo.Name) = 0 then TargetCanvas.Font.Color := $C06060; if TResource(Data.Field).FileInfo.Size = 0 then TargetCanvas.Font.Color := $2020A0; end; end; end; end; end; procedure TForm_Meta.VSTGetHint(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; var LineBreakStyle: TVTTooltipLineBreakStyle; var HintText: WideString); var data: PNodeData; CellText: WideString; i: Integer; links: TStrings; ifile: TResource; begin inherited; if Assigned(Node) then begin VSTGetText(Sender, Node, Column, ttNormal, CellText); if Length(CellText) > 0 then begin data := Sender.GetNodeData(Node); if data.Field is TDataField then begin case Column of 0,1: HintText := TDataField(data.Field).Description; 2: HintText := ''; end; end; if data.Field is TResource then begin ifile := TResource(data.Field); case Column of 0: HintText := 'FileID: ' + IntToStr(ifile.FileInfo.ID) + #13#10 + 'Name: ' + ifile.FileInfo.Name + #13#10 + 'Extension: ' + ifile.FileInfo.Extension + #13#10 + '.dat-size: ' + IntToStr(ifile.FileInfo.Size) + #13#10; end; end; end; end else HintText := ''; end; procedure TForm_Meta.VSTGetPopupMenu(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; const P: TPoint; var AskParent: Boolean; var PopupMenu: TPopupMenu); var data: PNodeData; begin inherited; AskParent := False; if Assigned(Node) then begin Sender.Selected[Node] := True; Sender.FocusedNode := Node; data := Sender.GetNodeData(Node); if Column = 0 then begin if TTreeElement(data.Field).ChildCount > 0 then PopupMenu := vst_popup else PopupMenu := nil; end; end; end; procedure TForm_Meta.vst_newRootClick(Sender: TObject); var data: PNodeData; form: TForm_BaseTemplate; begin inherited; data := VST.GetNodeData(VST.FocusedNode); form := nil; form := Form_Main.open_child('meta'); if form is TForm_Meta then TForm_Meta(form).SetRoot(data.Field); end; procedure TForm_Meta.vst_setRootClick(Sender: TObject); var data: PNodeData; begin inherited; data := VST.GetNodeData(VST.FocusedNode); SetRoot(data.Field); end; procedure TForm_Meta.FormClose(Sender: TObject; var Action: TCloseAction); begin // Meta.Free; inherited; end; procedure TForm_Meta.FormCreate(Sender: TObject); begin inherited; OnNewConnection := NewCon; VST.NodeDataSize := SizeOf(TNodeData); VST.Font.Charset := AppSettings.CharSet; VST.Clear; UpdateConList; end; end.