unit _main_editor;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ComCtrls, ExtCtrls, ImgList, ExtDlgs,
  SchemePaintObjects, SchemeVisual, Menus, ActnList, StdCtrls, Spin,
  ExtEdit, Buttons, DrawComboBox;

type
  TFormMain = class(TForm)
    StatusBar1: TStatusBar;
    PageControl1: TPageControl;
    SchemeVisualEditor2: TSchemeVisualEditor;
    Splitter1: TSplitter;
    Panel1: TPanel;
    SchemeVisualEditor3: TSchemeVisualEditor;
    SchemeVisualEditor1: TSchemeVisualEditor;
    SchemeDataEditor1: TSchemeDataEditor;
    Splitter2: TSplitter;
    SaveDialog1: TSaveDialog;
    OpenDialog1: TOpenDialog;
    OpenPictureDialog1: TOpenPictureDialog;
    ImageList1: TImageList;
    ActionList1: TActionList;
    ActionLoad: TAction;
    ActionSave: TAction;
    ActionObjectAdd: TAction;
    ActionObjectAddZone: TAction;
    ActionObjectDelete: TAction;
    ActionCenter: TAction;
    ActionZoomIn: TAction;
    ActionZoomOut: TAction;
    ActionZoomActual: TAction;
    ActionPictuteA: TAction;
    ActionLayerClear: TAction;
    PopupMenu1: TPopupMenu;
    Add1: TMenuItem;
    AddV1: TMenuItem;
    ActionState1: TMenuItem;
    ActionDelete1: TMenuItem;
    N1: TMenuItem;
    ZoomIn1: TMenuItem;
    ZoomOut1: TMenuItem;
    ActionZoomActual1: TMenuItem;
    N2: TMenuItem;
    Center1: TMenuItem;
    ActionObjectState: TAction;
    ActionObjectType: TAction;
    TabSheet1: TTabSheet;
    ActionObjectType1: TMenuItem;
    Panel10: TPanel;
    Label26: TLabel;
    Label37: TLabel;
    CheckBox6: TCheckBox;
    FloatEdit1: TFloatEdit;
    FloatEdit2: TFloatEdit;
    ActionObjectModified: TAction;
    ResizeOnOff1: TMenuItem;
    ActionObjectAddPoint: TAction;
    ActionObjectDeletePoint: TAction;
    Addpoint1: TMenuItem;
    DeletePoint1: TMenuItem;
    N3: TMenuItem;
    TabSheet2: TTabSheet;
    Panel2: TPanel;
    CheckBox1: TCheckBox;
    FloatEdit3: TFloatEdit;
    Label2: TLabel;
    Label38: TLabel;
    FloatEdit9: TFloatEdit;
    Label3: TLabel;
    Panel3: TPanel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    CheckBox2: TCheckBox;
    FloatEdit4: TFloatEdit;
    FloatEdit5: TFloatEdit;
    Panel4: TPanel;
    Label7: TLabel;
    Label8: TLabel;
    Label9: TLabel;
    CheckBox3: TCheckBox;
    FloatEdit6: TFloatEdit;
    FloatEdit7: TFloatEdit;
    Label21: TLabel;
    Label20: TLabel;
    SpinEditLaerIdAdd: TSpinEdit;
    Panel5: TPanel;
    Label1: TLabel;
    Label10: TLabel;
    Label11: TLabel;
    Label12: TLabel;
    Label56: TLabel;
    FloatEdit8: TFloatEdit;
    FloatEdit10: TFloatEdit;
    ComboBox1: TComboBox;
    IntEdit1: TIntEdit;
    Panel7: TPanel;
    Label13: TLabel;
    Label14: TLabel;
    Label15: TLabel;
    Label17: TLabel;
    Label18: TLabel;
    IntEdit2: TIntEdit;
    FillStyleComboBox1: TFillStyleComboBox;
    IntEdit4: TIntEdit;
    IntEdit5: TIntEdit;
    BitBtn8: TBitBtn;
    BitBtn7: TBitBtn;
    BitBtn10: TBitBtn;
    CheckBox4: TCheckBox;
    procedure FormCreate(Sender: TObject);
    procedure SchemeVisualEditor3MouseDown(Sender: TObject;
      Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure SchemeDataEditor1MouseDown(Sender, VisualSender: TObject;
      Button: TMouseButton; Shift: TShiftState;
      AObject: TAbstractPaintObject);
    procedure SchemeVisualEditor3MouseMove(Sender: TObject;
      Shift: TShiftState; X, Y: Integer);
    procedure SchemeVisualEditor3MouseUp(Sender: TObject;
      Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure ActionLoadExecute(Sender: TObject);
    procedure ActionSaveExecute(Sender: TObject);
    procedure ActionObjectAddExecute(Sender: TObject);
    procedure ActionObjectStateExecute(Sender: TObject);
    procedure ActionObjectTypeExecute(Sender: TObject);
    procedure PopupMenu1Popup(Sender: TObject);
    procedure ActionCenterExecute(Sender: TObject);
    procedure ActionZoomInExecute(Sender: TObject);
    procedure ActionPictuteAExecute(Sender: TObject);
    procedure CheckBox6Click(Sender: TObject);
    procedure FloatEdit1Change(Sender: TObject);
    procedure FloatEdit2Change(Sender: TObject);
    procedure ActionObjectModifiedExecute(Sender: TObject);
    procedure ActionObjectAddPointExecute(Sender: TObject);
    procedure CheckBox1Click(Sender: TObject);
    procedure FloatEdit3Change(Sender: TObject);
    procedure FloatEdit9Change(Sender: TObject);
    procedure CheckBox2Click(Sender: TObject);
    procedure FloatEdit4Change(Sender: TObject);
    procedure FloatEdit5Change(Sender: TObject);
    procedure CheckBox3Click(Sender: TObject);
    procedure FloatEdit6Change(Sender: TObject);
    procedure FloatEdit7Change(Sender: TObject);
    procedure FillStyleComboBox1Change(Sender: TObject);
    procedure FloatEdit10Change(Sender: TObject);
    procedure CheckBox4Click(Sender: TObject);
  private
    pCurrentPoint:TPoint;
    pSelectedObject:TAbstractPaintObject;            //тот который изменяем
    pSelectedSchemeVisualEditor:TSchemeVisualEditor; //окно с которым работаем
    procedure CreateLayer(AId:integer);
    procedure SetLayerParams(AId:integer);
    procedure SetCurrentPoint(X,Y:integer);
    procedure SetSelectedObject(Value:TObject);
    procedure SetSelectedSchemeVisual(Value:TObject);
    procedure UpdateStatusBarInfo;
    procedure TestEnabledActions;
    procedure LoadDemo;
  public
  end;

var
  FormMain: TFormMain;

//================================================================
implementation
{$R *.DFM}

uses _cv;

procedure TFormMain.FormCreate(Sender: TObject);
begin
  with Constraints do
  begin
    MinHeight:=Height;
    MinWidth:=Width;
  end;
  StatusBar1.Panels[1].Text := Format('Zoom A:%.1f  B:%.1f  C:%.1f',
    [SchemeVisualEditor3.Zoom,
    SchemeVisualEditor1.Zoom,
    SchemeVisualEditor2.Zoom]);
  ComboBox1.ItemIndex:=0;
  TestEnabledActions;
  WindowState:=wsMaximized;
  LoadDemo;
end;

procedure TFormMain.LoadDemo;
begin // Load demo example
  with SchemeDataEditor1 do
  try
    BeginUpdate;
    SetSelectedObject(nil);
    LoadFromFile(ExtractFilePath(Application.ExeName)+'DEMO_EXAMPLES.TXT');
  finally
    EndUpdate;
    RepaintAllVisualControls;
  end;
end;

//-------------------- Common -----------------------

procedure TFormMain.CreateLayer(AId:integer);
begin
  with SchemeDataEditor1 do
  begin
    try
      LayerDelete(AId);
    except
    end;
    LayerAdd(AId);
    SetLayerParams(AId);
  end;
end;

procedure TFormMain.SetLayerParams(AId:integer);
begin
  with SchemeDataEditor1 do
  try
    //BeginUpdate;     //if necessary
    Layer[AId].MinZoomForText:=10;
    Layer[AId].EnabledZoomForText:=false;
    LayerSetAllStateColors(AId,aclStateColors);
  finally
    //EndUpdate;
    //RepaintAllVisualControls;
  end;
end;

procedure TFormMain.SetCurrentPoint(X,Y:integer);
begin
  pCurrentPoint.X:=X;
  pCurrentPoint.Y:=Y;
end;

procedure TFormMain.UpdateStatusBarInfo;
var s:string;
begin
  s:='';
  if pSelectedObject<>nil then
  with pSelectedObject do
  begin
    s:=Format('For selected object: Layer ID: %d   Object Id: %d    State:%d    Hint: %s',
      [Layer.Id,Id,State,HintString]);
  end;
  StatusBar1.Panels[2].Text:=s;
end;

procedure TFormMain.SetSelectedObject(Value:TObject);
begin
  if pSelectedObject=Value then exit;
  if pSelectedObject<>nil then
    SchemeDataEditor1.ObjectSelectedDirect[pSelectedObject]:=false;//deselect old
  pSelectedObject:=TAbstractPaintObject(Value);
  if pSelectedObject<>nil then
    SchemeDataEditor1.ObjectSelectedDirect[pSelectedObject]:=true; //select new object
  UpdateStatusBarInfo;
  TestEnabledActions;
end;

procedure TFormMain.SetSelectedSchemeVisual(Value:TObject);
begin
  pSelectedSchemeVisualEditor:=TSchemeVisualEditor(Value);
end;

procedure TFormMain.TestEnabledActions;
var b:boolean;
begin
  b := pSelectedObject<>nil;
  ActionObjectDelete.Enabled   := b;
  ActionObjectState.Enabled    := b;
  ActionObjectType.Enabled     := b and
    (pSelectedObject is TPaintObjectShape);
  ActionObjectModified.Enabled := b;
  b := pSelectedObject is TPaintObjectZone;
  if b then b:=TPaintObjectZone(pSelectedObject).ResizedPoint>=0;
  ActionObjectAddPoint.Enabled    := b;
  ActionObjectDeletePoint.Enabled := b;
end;

procedure TFormMain.PopupMenu1Popup(Sender: TObject);
var p:TPoint;
begin
  GetCursorPos(p);
  p:=pSelectedSchemeVisualEditor.ScreenToClient(p);
  SetCurrentPoint(p.x,p.y);
end;

//--------------------------- Mouse -------------------------

procedure TFormMain.SchemeVisualEditor3MouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin  // MouseDown
  SetSelectedObject(nil);          //clear old selections
  SetSelectedSchemeVisual(Sender); //window Right or Left
  SetCurrentPoint(X,Y);
end;

procedure TFormMain.SchemeDataEditor1MouseDown(Sender,
  VisualSender: TObject; Button: TMouseButton; Shift: TShiftState;
  AObject: TAbstractPaintObject);
begin //SchemeData   Mouse Down  -> Object selected!
  SetSelectedObject(AObject);
end;

procedure TFormMain.SchemeVisualEditor3MouseMove(Sender: TObject;
  Shift: TShiftState; X, Y: Integer);
var a,b:extended;
begin //Mouse Move
  SetCurrentPoint(0,0);
  a:=x; b:=y;
  TSchemeVisual(Sender).TransformZoomAndOriginXYExt(a,b);//get real
  StatusBar1.Panels[0].Text := Format('%.2f   %.2f',[a,b]);
end;

procedure TFormMain.SchemeVisualEditor3MouseUp(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin //Mouse Up
end;

//------------------ Actions --------------------------

procedure TFormMain.ActionLoadExecute(Sender: TObject);
var s:string;
begin //Load
  if not OpenDialog1.Execute then exit;
  SaveDialog1.InitialDir:=OpenDialog1.InitialDir;
  s:=OpenDialog1.FileName;
  with SchemeDataEditor1 do
  try
    BeginUpdate;
    SetSelectedObject(nil);
    LayerClear;
    LoadFromFile(OpenDialog1.FileName);
  finally
    EndUpdate;
    RepaintAllVisualControls;
  end;
end;

procedure TFormMain.ActionSaveExecute(Sender: TObject);
begin // Save
  if SaveDialog1.Execute then
  begin
    OpenDialog1.InitialDir:=SaveDialog1.InitialDir;
    SchemeDataEditor1.SaveToFile(SaveDialog1.FileName);
  end;
end;

procedure TFormMain.ActionObjectAddExecute(Sender: TObject);
var p:TSchemeVisual;
  pp:TPoint;
  x,y,h,w:extended;
  i,j,a,b,ix,iy:integer;
begin // Add and Delete objects
  p:=pSelectedSchemeVisualEditor;
  x:=pCurrentPoint.x;
  y:=pCurrentPoint.y;
  p.TransformZoomAndOriginXYExt(x,y);
  SchemeDataEditor1.AlignPointToGrid(x,y);
  ix:=Trunc(x); iy:=Trunc(y);
  if (TAction(Sender)=ActionObjectAdd)or
   (TAction(Sender)=ActionObjectAddZone) then
  begin
    i:=SpinEditLaerIdAdd.Value; //default Layer for added objects or zone
    try
      SchemeDataEditor1.Layer[i];
    except
      CreateLayer(i);           //create layer if not exists
    end;
    j:=SchemeDataEditor1.Layer[i].GetObjectMaxId+1; //calculate ObjectId - not necessary
    if (TAction(Sender)=ActionObjectAdd) then
      SchemeDataEditor1.ObjectAddShapeExt(i,j,      //Add object
        x,y,ciObjectW,ciObjectH,ciObjectState,TShapeType(ciObjectType))
    else
      SchemeDataEditor1.ObjectAddZone(i,j,          //Add zone
           [Point(ix,iy),Point(ix+ciZoneW,iy),Point(ix,iy+ciZoneH)],
           ciZoneState,TBrushStyle(ciZoneType),IntToStr(j),Point(ix,iy));
    SchemeDataEditor1.Layer[i].Items[j].HintString:=
      Format('%s LayerID:%d ObjectID:%d',
        [SchemeDataEditor1.Layer[i].Items[j].ClassName,i,j]);
    SchemeDataEditor1.Layer[i].Sort; //Sort, not necessary
  end;
  if TAction(Sender)=ActionObjectDelete then
  begin  //Delete
    SchemeDataEditor1.ObjectDeleteDirect(pSelectedObject);
    pSelectedObject:=nil;
    SetSelectedObject(nil);
    StatusBar1.Panels[2].Text:='';
  end;
  TestEnabledActions;
end;

procedure TFormMain.ActionObjectStateExecute(Sender: TObject);
var i:integer;
begin //State
  i:=pSelectedObject.State;
  inc(i); if i>9 then i:=0;
  SchemeDataEditor1.ObjectStateDirect[pSelectedObject]:=i;
  UpdateStatusBarInfo;
end;

procedure TFormMain.ActionObjectTypeExecute(Sender: TObject);
var i:integer;b:boolean;
begin //Type - only for TPaintObjectShape
  i:=integer(TPaintObjectShape(pSelectedObject).ShapeType);
  inc(i); if i>5 then i:=0;
  with TPaintObjectShape(pSelectedObject) do
  begin //the type changes the size!
    b:=Visible;
    Visible:=false;
    SchemeDataEditor1.ObjectRepaintDirect(pSelectedObject);
    ShapeType:=TShapeType(i);
    Visible:=b;
    SchemeDataEditor1.ObjectRepaintDirect(pSelectedObject);
  end;
end;

procedure TFormMain.ActionCenterExecute(Sender: TObject);
var
  p,p2:TSchemeVisual;
  x,y:integer;
begin //Set centre in others windows
  x:=pCurrentPoint.x;
  y:=pCurrentPoint.y;
  pSelectedSchemeVisualEditor.TransformZoomAndOriginXY(x,y);
  if pSelectedSchemeVisualEditor=SchemeVisualEditor3 then
  begin
    p:=SchemeVisualEditor1;
    p2:=SchemeVisualEditor2;
  end;
  if pSelectedSchemeVisualEditor=SchemeVisualEditor2 then
  begin
    p:=SchemeVisualEditor1;
    p2:=SchemeVisualEditor3;
  end;
  if pSelectedSchemeVisualEditor=SchemeVisualEditor1 then
  begin
    p:=SchemeVisualEditor2;
    p2:=SchemeVisualEditor3;
  end;
  p.SetCenterToPoint(Point(X,Y));
  p2.SetCenterToPoint(Point(X,Y));
end;

procedure TFormMain.ActionZoomInExecute(Sender: TObject);
var
  delta:extended;
  x,y:integer;
  bmovetozenter:boolean;
begin// Zoom
  bmovetozenter:=(pCurrentPoint.x<>0)and(pCurrentPoint.y<>0);
  if bmovetozenter then
  begin //центровка
    x:=pCurrentPoint.x;
    y:=pCurrentPoint.y;
    pSelectedSchemeVisualEditor.TransformZoomAndOriginXY(x,y);
  end;
  if pSelectedSchemeVisualEditor=SchemeVisualEditor3 then
    delta:=crWindowZoomDeltaA;
  if pSelectedSchemeVisualEditor=SchemeVisualEditor1 then
    delta:=crWindowZoomDeltaB;
  if pSelectedSchemeVisualEditor=SchemeVisualEditor2 then
    delta:=crWindowZoomDeltaC;
  if (TAction(Sender)=ActionZoomOut) then
    delta:=-delta;
  if (TAction(Sender)=ActionZoomActual) then
    delta:=0;
  if delta=0 then pSelectedSchemeVisualEditor.Zoom:=1
  else pSelectedSchemeVisualEditor.Zoom:=pSelectedSchemeVisualEditor.Zoom+delta;
  if bmovetozenter then
  begin //центровка
    pSelectedSchemeVisualEditor.SetCenterToPoint(Point(x,y));
  end;
  StatusBar1.Panels[1].Text := Format('Zoom A:%.1f  B:%.1f  C:%.1f',
    [SchemeVisualEditor3.Zoom,
    SchemeVisualEditor1.Zoom,
    SchemeVisualEditor2.Zoom]);
end;

procedure TFormMain.ActionPictuteAExecute(Sender: TObject);
begin //Picture
  with OpenPictureDialog1 do
  begin
    if not OpenPictureDialog1.Execute then exit;
    SchemeVisualEditor1.Picture.LoadFromFile(FileName);
    SchemeVisualEditor2.Picture.LoadFromFile(FileName);
    SchemeVisualEditor3.Picture.LoadFromFile(FileName);
  end;
end;

procedure TFormMain.FloatEdit10Change(Sender: TObject);
begin // Set default params for adding
  ciObjectW     := FloatEdit8.Value;
  ciObjectH     := FloatEdit10.Value;
  ciObjectType  := ComboBox1.ItemIndex;
  ciObjectState := IntEdit1.Value;
  ciZoneW       := IntEdit4.Value;
  ciZoneH       := IntEdit5.Value;
  ciZoneType    := integer(FillStyleComboBox1.FillStyle);
  ciZoneState   := IntEdit2.Value;
  ciZoneCount   := 4;
end;

procedure TFormMain.CheckBox6Click(Sender: TObject);
begin //Align to Grid
  SchemeDataEditor1.AlignToGrid.Enabled:=CheckBox6.Checked;
end;

procedure TFormMain.FloatEdit1Change(Sender: TObject);
begin //Align to Grid X
  SchemeDataEditor1.AlignToGrid.DeltaX:=FloatEdit1.Value;
end;

procedure TFormMain.FloatEdit2Change(Sender: TObject);
begin //Align to Grid Y
  SchemeDataEditor1.AlignToGrid.DeltaY:=FloatEdit2.Value;
end;

procedure TFormMain.ActionObjectModifiedExecute(Sender: TObject);
begin // Set SelectedObject Modified On/Off
  if pSelectedObject=nil then exit;
  pSelectedObject.Resized:=not pSelectedObject.Resized;
  SchemeDataEditor1.ObjectRepaintDirect(pSelectedObject);
end;

procedure TFormMain.ActionObjectAddPointExecute(Sender: TObject);
begin //Add, Delete Point in Zone
  if pSelectedObject=nil then exit;
  if TAction(Sender)=ActionObjectDeletePoint then
    SchemeDataEditor1.ObjectDeleteResizedPointDirect(pSelectedObject);
  if TAction(Sender)=ActionObjectAddPoint then
    SchemeDataEditor1.ObjectAddResizedPointDirect(pSelectedObject);
end;

//------------------ Page: Windows --------------------------

procedure TFormMain.CheckBox1Click(Sender: TObject);
begin //Enabled editing Window A
  SchemeVisualEditor3.EditEnabled:=CheckBox1.Checked;
end;

procedure TFormMain.FloatEdit3Change(Sender: TObject);
begin //Min size for editing
  SchemeVisualEditor3.MinZoomForResize:=FloatEdit3.Value;
end;

procedure TFormMain.FloatEdit9Change(Sender: TObject);
begin //Delta for zooming A window
  crWindowZoomDeltaA:=FloatEdit9.Value;
end;

procedure TFormMain.CheckBox2Click(Sender: TObject);
begin //Enabled editing Window B
  SchemeVisualEditor1.EditEnabled:=CheckBox2.Checked;
end;

procedure TFormMain.FloatEdit4Change(Sender: TObject);
begin //Min size for editing
  SchemeVisualEditor1.MinZoomForResize:=FloatEdit4.Value;
end;

procedure TFormMain.FloatEdit5Change(Sender: TObject);
begin //Delta for zooming B window
  crWindowZoomDeltaB:=FloatEdit5.Value;
end;

procedure TFormMain.CheckBox3Click(Sender: TObject);
begin //Enabled editing Window C
  SchemeVisualEditor2.EditEnabled:=CheckBox3.Checked;
end;

procedure TFormMain.FloatEdit6Change(Sender: TObject);
begin //Min sze for editing
  SchemeVisualEditor2.MinZoomForResize:=FloatEdit6.Value;
end;

procedure TFormMain.FloatEdit7Change(Sender: TObject);
begin //Delta for zooming C window
  crWindowZoomDeltaC:=FloatEdit7.Value;
end;

procedure TFormMain.FillStyleComboBox1Change(Sender: TObject);
begin
  ciZoneType := integer(FillStyleComboBox1.FillStyle);
end;


procedure TFormMain.CheckBox4Click(Sender: TObject);
begin //Full drawing
  SchemeDataEditor1.FullMovedDrawing:=CheckBox4.Checked;
end;

end.
