5ff6758e7a
(Ronald, I hope you'll help me further ;)
3210 lines
90 KiB
ObjectPascal
3210 lines
90 KiB
ObjectPascal
{
|
||
Apophysis Copyright (C) 2001-2004 Mark Townsend
|
||
|
||
This program is free software; you can redistribute it and/or modify
|
||
it under the terms of the GNU General Public License as published by
|
||
the Free Software Foundation; either version 2 of the License, or
|
||
(at your option) any later version.
|
||
|
||
This program is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU General Public License for more details.
|
||
|
||
You should have received a copy of the GNU General Public License
|
||
along with this program; if not, write to the Free Software
|
||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||
}
|
||
//{$D-,L-,O+,Q-,R-,Y-,S-}
|
||
unit Editor;
|
||
|
||
interface
|
||
|
||
uses
|
||
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
|
||
ExtCtrls, StdCtrls, ComCtrls, Math, Menus, ToolWin, Registry, MyTypes,
|
||
ControlPoint, Render, cmap, Grids, ValEdit, Buttons, ImgList, TriangleGraph;
|
||
|
||
const
|
||
// PixelCountMax = 32768;
|
||
WM_PTHREAD_COMPLETE = WM_APP + 5438;
|
||
|
||
type
|
||
TEditForm = class(TForm)
|
||
GrphPnl: TPanel;
|
||
StatusBar: TStatusBar;
|
||
ControlPanel: TPanel;
|
||
lblTransform: TLabel;
|
||
PrevPnl: TPanel;
|
||
PreviewImage: TImage;
|
||
EditPopup: TPopupMenu;
|
||
MenuItem1: TMenuItem;
|
||
mnuDelete: TMenuItem;
|
||
mnuDuplicate: TMenuItem;
|
||
MenuItem2: TMenuItem;
|
||
mnuAdd: TMenuItem;
|
||
mnuAutoZoom: TMenuItem;
|
||
N1: TMenuItem;
|
||
mnuUndo: TMenuItem;
|
||
mnuRedo: TMenuItem;
|
||
QualityPopup: TPopupMenu;
|
||
mnuLowQuality: TMenuItem;
|
||
mnuMediumQuality: TMenuItem;
|
||
mnuHighQuality: TMenuItem;
|
||
N3: TMenuItem;
|
||
mnuResetLoc: TMenuItem;
|
||
N4: TMenuItem;
|
||
mnuFlipVertical: TMenuItem;
|
||
mnuFlipHorizontal: TMenuItem;
|
||
cbTransforms: TComboBox;
|
||
PageControl: TPageControl;
|
||
TriangleTab: TTabSheet;
|
||
tabXForm: TTabSheet;
|
||
lbla: TLabel;
|
||
Label1: TLabel;
|
||
Label2: TLabel;
|
||
Label3: TLabel;
|
||
Label4: TLabel;
|
||
Label5: TLabel;
|
||
Label6: TLabel;
|
||
Label29: TLabel;
|
||
txtA: TEdit;
|
||
txtB: TEdit;
|
||
txtC: TEdit;
|
||
txtD: TEdit;
|
||
txtE: TEdit;
|
||
txtF: TEdit;
|
||
txtP: TEdit;
|
||
txtSymmetry: TEdit;
|
||
tabVariations: TTabSheet;
|
||
VEVars: TValueListEditor;
|
||
tabColors: TTabSheet;
|
||
GroupBox1: TGroupBox;
|
||
scrlXFormColor: TScrollBar;
|
||
pnlXFormColor: TPanel;
|
||
txtXFormColor: TEdit;
|
||
GroupBox2: TGroupBox;
|
||
Label20: TLabel;
|
||
Label21: TLabel;
|
||
pnlBackColor: TPanel;
|
||
chkUseXFormColor: TCheckBox;
|
||
chkFlameBack: TCheckBox;
|
||
pnlReference: TPanel;
|
||
TriangleScrollBox: TScrollBox;
|
||
TrianglePanel: TPanel;
|
||
txtCy: TEdit;
|
||
txtCx: TEdit;
|
||
txtBy: TEdit;
|
||
txtBx: TEdit;
|
||
txtAy: TEdit;
|
||
txtAx: TEdit;
|
||
Label9: TLabel;
|
||
Label7: TLabel;
|
||
Label11: TLabel;
|
||
chkPreserve: TCheckBox;
|
||
btTrgRotateRight: TSpeedButton;
|
||
btTrgRotateLeft: TSpeedButton;
|
||
btTrgMoveUp: TSpeedButton;
|
||
btTrgMoveRight: TSpeedButton;
|
||
btTrgMoveLeft: TSpeedButton;
|
||
btTrgMoveDown: TSpeedButton;
|
||
btTrgScaleUp: TSpeedButton;
|
||
btTrgScaleDown: TSpeedButton;
|
||
rgPivot: TRadioGroup;
|
||
btTrgRotateRight90: TSpeedButton;
|
||
btTrgRotateLeft90: TSpeedButton;
|
||
txtTrgMoveValue: TComboBox;
|
||
txtTrgRotateValue: TComboBox;
|
||
txtTrgScaleValue: TComboBox;
|
||
Splitter1: TSplitter;
|
||
Splitter2: TSplitter;
|
||
EditorToolBar: TToolBar;
|
||
tbAdd: TToolButton;
|
||
tbDuplicate: TToolButton;
|
||
tbDelete: TToolButton;
|
||
ToolButton4: TToolButton;
|
||
tbMove: TToolButton;
|
||
tbRotate: TToolButton;
|
||
ToolButton1: TToolButton;
|
||
tbUndo: TToolButton;
|
||
tbRedo: TToolButton;
|
||
ToolButton5: TToolButton;
|
||
tbScale: TToolButton;
|
||
tbFlipHorz: TToolButton;
|
||
tbFlipVert: TToolButton;
|
||
tbFlipAllHorz: TToolButton;
|
||
tbFlipAllVert: TToolButton;
|
||
tbSelect: TToolButton;
|
||
btTrgMoveLU: TSpeedButton;
|
||
btTrgMoveLD: TSpeedButton;
|
||
btTrgMoveRU: TSpeedButton;
|
||
btTrgMoveRD: TSpeedButton;
|
||
EditorTB: TImageList;
|
||
Label8: TLabel;
|
||
pnlGridColor1: TPanel;
|
||
pnlGridColor2: TPanel;
|
||
PreviewToolBar: TToolBar;
|
||
tbFullView: TToolButton;
|
||
tbLowQ: TToolButton;
|
||
tbMedQ: TToolButton;
|
||
ToolButton7: TToolButton;
|
||
tbResetLoc: TToolButton;
|
||
tbHiQ: TToolButton;
|
||
ToolButton9: TToolButton;
|
||
Panel1: TPanel;
|
||
ColorImage: TImage;
|
||
TabSheet4: TTabSheet;
|
||
vleVariables: TValueListEditor;
|
||
procedure vleVariablesValidate(Sender: TObject; ACol, ARow: Integer; const KeyName, KeyValue: string);
|
||
procedure vleVariablesKeyPress(Sender: TObject; var Key: Char);
|
||
procedure vleVariablesExit(Sender: TObject);
|
||
procedure FormCreate(Sender: TObject);
|
||
procedure GraphImageMouseMove(Sender: TObject; Shift: TShiftState; X,
|
||
Y: integer);
|
||
procedure GraphImageMouseDown(Sender: TObject; Button: TMouseButton;
|
||
Shift: TShiftState; X, Y: integer);
|
||
procedure GraphImageMouseUp(Sender: TObject; Button: TMouseButton;
|
||
Shift: TShiftState; X, Y: integer);
|
||
procedure FormShow(Sender: TObject);
|
||
procedure mnuDeleteClick(Sender: TObject);
|
||
procedure mnuAddClick(Sender: TObject);
|
||
procedure mnuDupClick(Sender: TObject);
|
||
procedure mnuAutoZoomClick(Sender: TObject);
|
||
// procedure mnuXFlipClick(Sender: TObject);
|
||
// procedure mnuYFlipClick(Sender: TObject);
|
||
procedure btnCloseClick(Sender: TObject);
|
||
procedure FormResize(Sender: TObject);
|
||
procedure txtPKeyPress(Sender: TObject; var Key: Char);
|
||
procedure CornerEditKeyPress(Sender: TObject; var Key: Char);
|
||
procedure CornerEditExit(Sender: TObject);
|
||
procedure txtPExit(Sender: TObject);
|
||
procedure DrawPreview;
|
||
procedure FormClose(Sender: TObject; var Action: TCloseAction);
|
||
procedure mnuUndoClick(Sender: TObject);
|
||
procedure mnuRedoClick(Sender: TObject);
|
||
procedure FormDestroy(Sender: TObject);
|
||
procedure mnuLowQualityClick(Sender: TObject);
|
||
procedure mnuHighQualityClick(Sender: TObject);
|
||
procedure mnuMediumQualityClick(Sender: TObject);
|
||
procedure mnuResetLocClick(Sender: TObject);
|
||
procedure mnuVerticalFlipAllClick(Sender: TObject);
|
||
procedure mnuHorizintalFlipAllClick(Sender: TObject);
|
||
procedure mnuFlipVerticalClick(Sender: TObject);
|
||
procedure mnuFlipHorizontalClick(Sender: TObject);
|
||
procedure GraphImageDblClick(Sender: TObject);
|
||
procedure cbTransformsChange(Sender: TObject);
|
||
procedure CoefKeyPress(Sender: TObject; var Key: Char);
|
||
procedure CoefExit(Sender: TObject);
|
||
procedure scrlXFormColorScroll(Sender: TObject;
|
||
ScrollCode: TScrollCode; var ScrollPos: Integer);
|
||
procedure scrlXFormColorChange(Sender: TObject);
|
||
procedure chkUseXFormColorClick(Sender: TObject);
|
||
procedure chkFlameBackClick(Sender: TObject);
|
||
procedure pnlBackColorClick(Sender: TObject);
|
||
procedure pnlReferenceClick(Sender: TObject);
|
||
procedure txtXFormColorExit(Sender: TObject);
|
||
procedure txtXFormColorKeyPress(Sender: TObject; var Key: Char);
|
||
procedure txtSymmetryExit(Sender: TObject);
|
||
procedure txtSymmetryKeyPress(Sender: TObject; var Key: Char);
|
||
procedure VEVarsKeyPress(Sender: TObject; var Key: Char);
|
||
procedure VEVarsExit(Sender: TObject);
|
||
procedure VEVarsValidate(Sender: TObject; ACol, ARow: Integer;
|
||
const KeyName, KeyValue: String);
|
||
// procedure mnuRotateRightClick(Sender: TObject);
|
||
// procedure mnuRotateLeftClick(Sender: TObject);
|
||
// procedure mnuScaleUpClick(Sender: TObject);
|
||
// procedure mnuScaleDownClick(Sender: TObject);
|
||
|
||
procedure btTrgRotateLeftClick(Sender: TObject);
|
||
procedure btTrgRotateRightClick(Sender: TObject);
|
||
procedure btTrgRotateLeft90Click(Sender: TObject);
|
||
procedure btTrgRotateRight90Click(Sender: TObject);
|
||
procedure TrgMove(dx, dy: double);
|
||
procedure btTrgMoveLeftClick(Sender: TObject);
|
||
procedure btTrgMoveRightClick(Sender: TObject);
|
||
procedure btTrgMoveUpClick(Sender: TObject);
|
||
procedure btTrgMoveDownClick(Sender: TObject);
|
||
procedure btTrgScaleUpClick(Sender: TObject);
|
||
procedure btTrgScaleDownClick(Sender: TObject);
|
||
procedure editKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
|
||
procedure splitterMoved(Sender: TObject);
|
||
procedure tbSelectClick(Sender: TObject);
|
||
procedure btTrgMoveLUClick(Sender: TObject);
|
||
procedure btTrgMoveLDClick(Sender: TObject);
|
||
procedure btTrgMoveRUClick(Sender: TObject);
|
||
procedure btTrgMoveRDClick(Sender: TObject);
|
||
procedure editMouseWheel(Sender: TObject; Shift: TShiftState;
|
||
WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
|
||
procedure PreviewImageDblClick(Sender: TObject);
|
||
procedure editKeyPress(Sender: TObject; var Key: Char);
|
||
procedure rgPivotClicked(Sender: TObject);
|
||
procedure tbEditModeClick(Sender: TObject);
|
||
procedure pnlGridColor1Click(Sender: TObject);
|
||
procedure pnlGridColor2Click(Sender: TObject);
|
||
|
||
procedure VEVarsMouseDown(Sender: TObject; Button: TMouseButton;
|
||
Shift: TShiftState; X, Y: Integer);
|
||
procedure VEVarsMouseMove(Sender: TObject; Shift: TShiftState; X,
|
||
Y: Integer);
|
||
procedure VEVarsMouseUp(Sender: TObject; Button: TMouseButton;
|
||
Shift: TShiftState; X, Y: Integer);
|
||
procedure VEVarsDblClick(Sender: TObject);
|
||
procedure VEVarsDrawCell(Sender: TObject; ACol, ARow: Integer;
|
||
Rect: TRect; State: TGridDrawState);
|
||
|
||
procedure cbTransformsDrawItem(Control: TWinControl; Index: Integer;
|
||
Rect: TRect; State: TOwnerDrawState);
|
||
procedure cbKeyDown(Sender: TObject; var Key: Word;
|
||
Shift: TShiftState);
|
||
|
||
procedure tbFullViewClick(Sender: TObject);
|
||
|
||
procedure ColorImageMouseDown(Sender: TObject; Button: TMouseButton;
|
||
Shift: TShiftState; X, Y: Integer);
|
||
procedure ColorImageMouseMove(Sender: TObject; Shift: TShiftState; X,
|
||
Y: Integer);
|
||
procedure ColorImageMouseUp(Sender: TObject; Button: TMouseButton;
|
||
Shift: TShiftState; X, Y: Integer);
|
||
|
||
private
|
||
TriangleGraph: TTriangleGraph;
|
||
bm: TBitmap;
|
||
cmap: TColorMap;
|
||
// cp1: TControlPoint;
|
||
PreviewDensity: double;
|
||
|
||
// --Z--
|
||
graphDragMode, dragged: boolean;
|
||
editMode: (modeMove, modeRotate, modeScale);
|
||
key_handled: boolean; // hack... there must be a better way to do this :-\
|
||
|
||
MousePos: TPoint; // in screen coordinates
|
||
mouseOverTriangle: integer;
|
||
mouseOverCorner: integer;
|
||
|
||
varDragMode: boolean;
|
||
varDragIndex, varDragPos: integer;
|
||
varMM: boolean; //hack?
|
||
|
||
// --Z-- variables moved from outside
|
||
GraphZoom: double;
|
||
CornerCaught: boolean;
|
||
TriangleCaught: boolean;
|
||
// SelectedTriangle: integer; // outside only for scripting (??)
|
||
SelectedCorner: integer;
|
||
SelectMode: boolean;
|
||
// Drawing: boolean;
|
||
HasChanged: boolean;
|
||
|
||
oldx, oldy: double;
|
||
// --Z--
|
||
olddist: double;
|
||
Pivot: TSPoint;
|
||
VarsCache: array[0..64] of double; // hack
|
||
|
||
colorDrag, colorChanged: boolean;
|
||
colorDragX, colorOldX: integer;
|
||
// --
|
||
|
||
{ Options }
|
||
UseFlameBackground, UseTransformColors: boolean;
|
||
BackGroundColor, ReferenceTrianglecolor: integer;
|
||
GridColor1, GridColor2: integer; // --Z--
|
||
|
||
procedure UpdateFlameX;
|
||
procedure UpdateFlame(DrawMain: boolean);
|
||
procedure DeleteTriangle(t: integer);
|
||
|
||
function GetPivot: TSPoint;
|
||
function GetTriangleColor(n: integer): TColor;
|
||
|
||
// --Z-- functions moved from outside (?)
|
||
procedure ShowSelectedInfo;
|
||
procedure Scale(var fx, fy: double; x, y, Width, Height: integer);
|
||
procedure ReadjustWeights(var cp: TControlPoint);
|
||
|
||
public
|
||
cp: TControlPoint;
|
||
Render: TRenderer;
|
||
|
||
SelectedTriangle: integer;
|
||
|
||
procedure UpdateDisplay(preview_only: boolean = false);
|
||
procedure AutoZoom;
|
||
procedure DrawGraph;
|
||
end;
|
||
|
||
const
|
||
clr: array[-1..15] of TColor = (clGray,
|
||
clYellow, $ff55ff, clRed, clLime, clAqua, clGreen, $007fff, clNavy,
|
||
clOlive, clPurple, clTeal, clBlue, clFuchsia, clMoneyGreen, clSkyBlue, clCream);
|
||
var
|
||
EditForm: TEditForm;
|
||
pcenterx, pcentery, pscale: double;
|
||
|
||
function ColorValToColor(c: TColorMap; index: double): TColor;
|
||
function FlipTriangleVertical(t: TTriangle): TTriangle;
|
||
function FlipTriangleHorizontal(t: TTriangle): TTriangle;
|
||
function RotateTriangle(t: TTriangle; rad: double): TTriangle;
|
||
function OffsetTriangle(t: TTriangle; range: double): TTriangle;
|
||
function ScaleTriangle(t: TTriangle; scale: double): TTriangle;
|
||
function RotateTriangleCenter(t: TTriangle; rad: double): TTriangle;
|
||
function RotateTrianglePoint(t: TTriangle; x, y, rad: double): TTriangle;
|
||
function Centroid(t: TTriangle): TSPoint;
|
||
function OffsetTriangleRandom(t: TTriangle): TTriangle;
|
||
function ScaleTriangleCenter(t: TTriangle; scale: double): TTriangle;
|
||
function ScaleTrianglePoint(t: TTriangle; x, y, scale: double): TTriangle;
|
||
procedure ScaleAll;
|
||
|
||
implementation
|
||
|
||
uses
|
||
Main, Global, Adjust, Mutate, XformMan;
|
||
|
||
const
|
||
SUB_BATCH_SIZE = 1000;
|
||
SC_MyMenuItem1 = WM_USER + 1;
|
||
|
||
var
|
||
oldTriangle: TTriangle;
|
||
gCenterX: double;
|
||
gCentery: double;
|
||
gxlength: double;
|
||
gylength: double;
|
||
|
||
{$R *.DFM}
|
||
|
||
{ Triangle transformations }
|
||
|
||
function OffsetTriangleRandom(t: TTriangle): TTriangle;
|
||
var
|
||
r: integer;
|
||
begin
|
||
r := random(3);
|
||
Result.x[r] := t.x[r] + random - 0.5;
|
||
Result.y[r] := t.y[r] + random - 0.5;
|
||
end;
|
||
|
||
function FlipTriangleVertical(t: TTriangle): TTriangle;
|
||
begin
|
||
Result := t;
|
||
Result.y[0] := -t.y[0];
|
||
Result.y[1] := -t.y[1];
|
||
Result.y[2] := -t.y[2];
|
||
end;
|
||
|
||
function FlipTriangleHorizontal(t: TTriangle): TTriangle;
|
||
begin
|
||
Result := t;
|
||
Result.x[0] := -t.x[0];
|
||
Result.x[1] := -t.x[1];
|
||
Result.x[2] := -t.x[2];
|
||
end;
|
||
|
||
function ScaleTriangle(t: TTriangle; scale: double): TTriangle;
|
||
begin
|
||
Result.y[0] := scale * t.y[0];
|
||
Result.y[1] := scale * t.y[1];
|
||
Result.y[2] := scale * t.y[2];
|
||
Result.x[0] := scale * t.x[0];
|
||
Result.x[1] := scale * t.x[1];
|
||
Result.x[2] := scale * t.x[2];
|
||
end;
|
||
|
||
function Centroid(t: TTriangle): TSPoint;
|
||
begin
|
||
Result.x := (t.x[0] + t.x[1] + t.x[2]) / 3;
|
||
Result.y := (t.y[0] + t.y[1] + t.y[2]) / 3;
|
||
end;
|
||
|
||
function ScaleTriangleCenter(t: TTriangle; scale: double): TTriangle;
|
||
var
|
||
xr, yr: double;
|
||
z: TSPoint;
|
||
begin
|
||
z := Centroid(t);
|
||
xr := z.x;
|
||
yr := z.y;
|
||
Result.y[0] := scale * (t.y[0] - yr) + yr;
|
||
Result.y[1] := scale * (t.y[1] - yr) + yr;
|
||
Result.y[2] := scale * (t.y[2] - yr) + yr;
|
||
Result.x[0] := scale * (t.x[0] - xr) + xr;
|
||
Result.x[1] := scale * (t.x[1] - xr) + xr;
|
||
Result.x[2] := scale * (t.x[2] - xr) + xr;
|
||
end;
|
||
|
||
function ScaleTrianglePoint(t: TTriangle; x, y, scale: double): TTriangle;
|
||
begin
|
||
Result.y[0] := scale * (t.y[0] - y) + y;
|
||
Result.y[1] := scale * (t.y[1] - y) + y;
|
||
Result.y[2] := scale * (t.y[2] - y) + y;
|
||
Result.x[0] := scale * (t.x[0] - x) + x;
|
||
Result.x[1] := scale * (t.x[1] - x) + x;
|
||
Result.x[2] := scale * (t.x[2] - x) + x;
|
||
end;
|
||
|
||
function RotateTriangle(t: TTriangle; rad: double): TTriangle; //rad in Radians
|
||
var
|
||
i: integer;
|
||
begin
|
||
for i := 0 to 2 do
|
||
begin
|
||
Result.x[i] := t.x[i] * cos(rad) - t.y[i] * sin(rad);
|
||
Result.y[i] := t.x[i] * sin(rad) + t.y[i] * cos(rad);
|
||
end;
|
||
end;
|
||
|
||
function OffsetTriangle(t: TTriangle; range: double): TTriangle;
|
||
var
|
||
i: integer;
|
||
r: double;
|
||
begin
|
||
r := (random * 2 * range) - range;
|
||
for i := 0 to 2 do
|
||
begin
|
||
Result.x[i] := t.x[i] + r;
|
||
Result.y[i] := t.y[i] + r;
|
||
end;
|
||
end;
|
||
|
||
procedure ScaleAll;
|
||
var
|
||
i, j: integer;
|
||
begin
|
||
for i := 0 to 2 do
|
||
begin
|
||
MainTriangles[-1].y[i] := MainTriangles[-1].y[i] * 0.2;
|
||
MainTriangles[-1].x[i] := MainTriangles[-1].x[i] * 0.2;
|
||
end;
|
||
for j := 0 to Transforms - 1 do
|
||
for i := 0 to 2 do
|
||
begin
|
||
MainTriangles[j].y[i] := MainTriangles[j].y[i] * 0.2;
|
||
MainTriangles[j].x[i] := MainTriangles[j].x[i] * 0.2;
|
||
end;
|
||
end;
|
||
|
||
function RotateTriangleCenter(t: TTriangle; rad: double): TTriangle;
|
||
var
|
||
i: integer;
|
||
xr, yr: double;
|
||
z: TSPoint;
|
||
begin
|
||
z := Centroid(t);
|
||
xr := z.x;
|
||
yr := z.y;
|
||
for i := 0 to 2 do
|
||
begin
|
||
Result.x[i] := xr + (t.x[i] - xr) * cos(rad) -
|
||
(t.y[i] - yr) * sin(rad);
|
||
Result.y[i] := yr + (t.x[i] - xr) * sin(rad) +
|
||
(t.y[i] - yr) * cos(rad);
|
||
end;
|
||
end;
|
||
|
||
function RotateTrianglePoint(t: TTriangle; x, y, rad: double): TTriangle;
|
||
var
|
||
i: integer;
|
||
xr, yr: double;
|
||
begin
|
||
xr := x;
|
||
yr := y;
|
||
for i := 0 to 2 do
|
||
begin
|
||
Result.x[i] := xr + (t.x[i] - xr) * cos(rad) -
|
||
(t.y[i] - yr) * sin(rad);
|
||
Result.y[i] := yr + (t.x[i] - xr) * sin(rad) +
|
||
(t.y[i] - yr) * cos(rad);
|
||
end;
|
||
end;
|
||
|
||
|
||
function ColorValToColor(c: TColorMap; index: double): TColor;
|
||
var
|
||
i: integer;
|
||
begin
|
||
i := Trunc(Index * 255);
|
||
result := c[i][2] shl 16 + c[i][1] shl 8 + c[i][0];
|
||
end;
|
||
|
||
procedure TEditForm.UpdateDisplay(preview_only: boolean = false);
|
||
var
|
||
i: integer;
|
||
pw, ph: integer;
|
||
r: double;
|
||
begin
|
||
cp.copy(MainCp);
|
||
|
||
pw := PrevPnl.Width - 2;
|
||
ph := PrevPnl.Height - 2;
|
||
if (cp.width / cp.height) > (PrevPnl.Width / PrevPnl.Height) then
|
||
begin
|
||
PreviewImage.Width := pw;
|
||
r := cp.width / PreviewImage.Width;
|
||
PreviewImage.height := round(cp.height / r);
|
||
PreviewImage.Left := 1;
|
||
PreviewImage.Top := (ph - PreviewImage.Height) div 2;
|
||
end
|
||
else begin
|
||
PreviewImage.Height := ph;
|
||
r := cp.height / PreviewImage.height;
|
||
PreviewImage.Width := round(cp.Width / r);
|
||
PreviewImage.Top := 1;
|
||
PreviewImage.Left := (pw - PreviewImage.Width) div 2;
|
||
end;
|
||
|
||
AdjustScale(cp, PreviewImage.Width, PreviewImage.Height);
|
||
|
||
DrawPreview;
|
||
if preview_only then exit;
|
||
|
||
cp.cmap := MainCp.cmap;
|
||
cmap := MainCp.cmap;
|
||
|
||
cbTransforms.Clear;
|
||
for i := 0 to Transforms - 1 do
|
||
cbTransforms.Items.Add(IntToStr(i + 1));
|
||
|
||
ShowSelectedInfo;
|
||
AutoZoom;
|
||
DrawGraph;
|
||
end;
|
||
|
||
procedure TEditForm.DrawPreview;
|
||
begin
|
||
//Render.Stop;
|
||
cp.sample_density := PreviewDensity;
|
||
cp.spatial_oversample := defOversample;
|
||
cp.spatial_filter_radius := defFilterRadius;
|
||
if mnuResetLoc.checked then
|
||
begin
|
||
cp.zoom := 0;
|
||
cp.CalcBoundbox;
|
||
end
|
||
else
|
||
begin
|
||
cp.zoom := MainCp.zoom;
|
||
cp.center[0] := MainCp.Center[0];
|
||
cp.center[1] := MainCp.Center[1];
|
||
end;
|
||
cp.cmap := MainCp.cmap;
|
||
Render.Compatibility := compatibility;
|
||
Render.SetCP(cp);
|
||
Render.Render;
|
||
PreviewImage.Picture.Bitmap.Assign(Render.GetImage);
|
||
PreviewImage.refresh;
|
||
end;
|
||
|
||
procedure TEditForm.ReadjustWeights(var cp: TControlPoint);
|
||
{ Thanks to Rudy...code from Chaos}
|
||
var
|
||
total, othertotals, excess: double;
|
||
t, i: integer;
|
||
begin
|
||
t := NumXForms(cp);
|
||
{ /* First determine the excess. */ }
|
||
total := 0.0;
|
||
othertotals := 0.0;
|
||
for i := 0 to T - 1 do
|
||
if cp.xform[i].density <> 0.0 then
|
||
begin
|
||
total := total + cp.xform[i].density;
|
||
if (i <> SelectedTriangle) then
|
||
othertotals := othertotals + cp.xform[i].density;
|
||
end;
|
||
{ /* Now we need to fix'em */ }
|
||
//z excess := total - 1.0;
|
||
excess := 1.0 - (total - 1.0)/othertotals; // --Z--
|
||
for i := 0 to T - 1 do
|
||
if (i <> SelectedTriangle) and (cp.xform[i].density <> 0) then
|
||
//z cp.xform[i].density := cp.xform[i].density - cp.xform[i].density / othertotals * excess;
|
||
cp.xform[i].density := cp.xform[i].density * excess; // --Z--
|
||
end;
|
||
|
||
procedure TEditForm.ShowSelectedInfo;
|
||
var
|
||
t: integer;
|
||
i: integer;
|
||
a, b, c, d, e, f: double;
|
||
v: double;
|
||
val: double;
|
||
begin
|
||
t := SelectedTriangle; // why 't' ?
|
||
|
||
assert(t < Transforms); // ?? hmm..
|
||
|
||
if (t >= Transforms) then t := Transforms - 1;
|
||
//if EditForm.cbTransforms.ItemIndex <> t then EditForm.cbTransforms.ItemIndex := t;
|
||
EditForm.cbTransforms.ItemIndex := t;
|
||
//select combobox item
|
||
EditForm.txtAx.text := Format('%.6g', [MainTriangles[t].x[0]]);
|
||
EditForm.txtAy.text := Format('%.6g', [MainTriangles[t].y[0]]);
|
||
EditForm.txtBx.text := Format('%.6g', [MainTriangles[t].x[1]]);
|
||
EditForm.txtBy.text := Format('%.6g', [MainTriangles[t].y[1]]);
|
||
EditForm.txtCx.text := Format('%.6g', [MainTriangles[t].x[2]]);
|
||
EditForm.txtCy.text := Format('%.6g', [MainTriangles[t].y[2]]);
|
||
EditForm.lblTransform.Refresh;
|
||
EditForm.txtAx.Refresh;
|
||
EditForm.txtAy.Refresh;
|
||
EditForm.txtBx.Refresh;
|
||
EditForm.txtBy.Refresh;
|
||
EditForm.txtCx.Refresh;
|
||
EditForm.txtCy.Refresh;
|
||
a := EditForm.cp.xform[t].c[0][0];
|
||
b := EditForm.cp.xform[t].c[1][0];
|
||
c := EditForm.cp.xform[t].c[0][1];
|
||
d := EditForm.cp.xform[t].c[1][1];
|
||
e := EditForm.cp.xform[t].c[2][0];
|
||
f := EditForm.cp.xform[t].c[2][1];
|
||
|
||
EditForm.txtA.text := Format('%.6g', [a]);
|
||
EditForm.txtB.text := Format('%.6g', [b]);
|
||
EditForm.txtC.text := Format('%.6g', [c]);
|
||
EditForm.txtD.text := Format('%.6g', [d]);
|
||
EditForm.txtE.text := Format('%.6g', [e]);
|
||
EditForm.txtF.text := Format('%.6g', [f]);
|
||
|
||
EditForm.txtP.text := Format('%.6g', [EditForm.cp.xform[t].density]);
|
||
EditForm.txtSymmetry.text := Format('%.6g', [EditForm.cp.xform[t].symmetry]);
|
||
EditForm.txtA.Refresh;
|
||
EditForm.txtB.Refresh;
|
||
EditForm.txtC.Refresh;
|
||
EditForm.txtD.Refresh;
|
||
EditForm.txtE.Refresh;
|
||
EditForm.txtF.Refresh;
|
||
EditForm.txtP.Refresh;
|
||
EditForm.pnlXFormColor.Color := ColorValToColor(EditForm.cp.cmap, EditForm.cp.xform[t].color);
|
||
EditForm.txtXFormColor.Text := Format('%1.3f', [cp.xform[t].color]);//FloatToStr(EditForm.cp.xform[t].color);
|
||
EditForm.scrlXFormcolor.Position := Trunc(EditForm.cp.xform[t].color * scrlXFormColor.Max);
|
||
|
||
for i := 0 to NRVAR-1 do begin
|
||
v:=EditForm.cp.xform[SelectedTriangle].vars[i];
|
||
if v <> VarsCache[i] then
|
||
begin
|
||
VarsCache[i]:=v;
|
||
EditForm.VEVars.Values[VarNames(i)] := Format('%.6g', [v]);
|
||
end;
|
||
end;
|
||
|
||
for i:= 0 to GetNrVariableNames - 1 do begin
|
||
EditForm.cp.xform[SelectedTriangle].GetVariable(GetVariableNameAt(i), val);
|
||
EditForm.vleVariables.Values[GetVariableNameAt(i)] := Format('%.6g', [val]);
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.Scale(var fx, fy: double; x, y, Width, Height: integer);
|
||
var
|
||
sc: double;
|
||
begin
|
||
sc := 50 * GraphZoom;
|
||
fx := (x - (Width / 2)) / sc + gCenterX;
|
||
fy := -((y - (Height / 2)) / sc - gCentery);
|
||
end;
|
||
|
||
procedure TEditForm.AutoZoom;
|
||
var
|
||
i, j: integer;
|
||
xminz, yminz, xmaxz, ymaxz: double;
|
||
begin
|
||
xminz := 0;
|
||
yminz := 0;
|
||
xmaxz := 0;
|
||
ymaxz := 0;
|
||
for i := -1 to Transforms - 1 do
|
||
begin
|
||
for j := 0 to 2 do
|
||
begin
|
||
if MainTriangles[i].x[j] < xminz then xminz := MainTriangles[i].x[j];
|
||
if MainTriangles[i].y[j] < yminz then yminz := MainTriangles[i].y[j];
|
||
if MainTriangles[i].x[j] > xmaxz then xmaxz := MainTriangles[i].x[j];
|
||
if MainTriangles[i].y[j] > ymaxz then ymaxz := MainTriangles[i].y[j];
|
||
end;
|
||
end;
|
||
gxlength := xmaxz - xminz;
|
||
gylength := ymaxz - yminz;
|
||
gCenterX := xminz + gxlength / 2;
|
||
gCentery := yminz + gylength / 2;
|
||
if gxlength >= gylength then
|
||
begin
|
||
GraphZoom := TriangleGraph.Width / 60 / gxlength;
|
||
end
|
||
else
|
||
begin
|
||
GraphZoom := TriangleGraph.Height / 60 / gylength;
|
||
end;
|
||
EditForm.StatusBar.Panels[2].Text := Format('Zoom: %f', [GraphZoom]);
|
||
end;
|
||
|
||
procedure TEditForm.UpdateFlameX;
|
||
var
|
||
i: integer;
|
||
begin
|
||
for i := 0 to transforms - 1 do
|
||
begin
|
||
// CP_compute(cp1, Triangles[i], Triangles[-1], i);
|
||
solve3(MainTriangles[-1].x[0], MainTriangles[-1].y[0], MainTriangles[i].x[0],
|
||
MainTriangles[-1].x[1], MainTriangles[-1].y[1], MainTriangles[i].x[1],
|
||
MainTriangles[-1].x[2], MainTriangles[-1].y[2], MainTriangles[i].x[2],
|
||
cp.xform[i].c[0][0], cp.xform[i].c[1][0], cp.xform[i].c[2][0]);
|
||
|
||
solve3(MainTriangles[-1].x[0], MainTriangles[-1].y[0], MainTriangles[i].y[0],
|
||
MainTriangles[-1].x[1], MainTriangles[-1].y[1], MainTriangles[i].y[1],
|
||
MainTriangles[-1].x[2], MainTriangles[-1].y[2], MainTriangles[i].y[2],
|
||
cp.xform[i].c[0][1], cp.xform[i].c[1][1], cp.xform[i].c[2][1]);
|
||
end;
|
||
|
||
GetXForms(cp, MainTriangles, transforms);
|
||
if not chkPreserve.checked then ComputeWeights(cp, MainTriangles, transforms);
|
||
DrawPreview;
|
||
ShowSelectedInfo;
|
||
DrawGraph;
|
||
end;
|
||
|
||
procedure TEditForm.UpdateFlame(DrawMain: boolean);
|
||
begin
|
||
//; MainForm.StopThread;
|
||
StatusBar.Panels[2].Text := Format('Zoom: %f', [GraphZoom]);
|
||
GetXForms(cp, MainTriangles, transforms);
|
||
if not chkPreserve.Checked then ComputeWeights(cp, MainTriangles, transforms);
|
||
DrawPreview;
|
||
ShowSelectedInfo;
|
||
DrawGraph;
|
||
if DrawMain then begin
|
||
MainForm.StopThread;
|
||
MainCp.Copy(cp);
|
||
MainCp.cmap := cmap;
|
||
if mnuResetLoc.checked then begin
|
||
MainCp.zoom := 0;
|
||
MainForm.center[0] := cp.center[0];
|
||
MainForm.center[1] := cp.center[1];
|
||
end;
|
||
// if AdjustForm.Visible then AdjustForm.UpdateDisplay;
|
||
if MutateForm.Visible then MutateForm.UpdateDisplay;
|
||
MainForm.RedrawTimer.enabled := true;
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.DeleteTriangle(t: integer);
|
||
var
|
||
i, j: integer;
|
||
begin
|
||
if Transforms > 2 then
|
||
{ Can't have less than 2 transofms}
|
||
begin
|
||
MainForm.UpdateUndo;
|
||
if t = (Transforms - 1) then
|
||
{ Last triangle...just reduce number}
|
||
begin
|
||
Transforms := Transforms - 1;
|
||
SelectedTriangle := Transforms - 1;
|
||
cp.xform[transforms].density := 0;
|
||
cbTransforms.Clear;
|
||
UpdateFlame(True);
|
||
end
|
||
else
|
||
begin
|
||
for i := t to Transforms - 2 do
|
||
begin
|
||
{ copy higher transforms down }
|
||
MainTriangles[i] := MainTriangles[i + 1];
|
||
cp.xform[i].density := cp.xform[i + 1].density;
|
||
cp.xform[i].color := cp.xform[i + 1].color;
|
||
cp.xform[i].symmetry := cp.xform[i + 1].symmetry;
|
||
for j := 0 to NRVAR - 1 do
|
||
cp.xform[i].vars[j] := cp.xform[i + 1].vars[j];
|
||
end;
|
||
Transforms := Transforms - 1;
|
||
cp.xform[transforms].density := 0;
|
||
UpdateFlame(True);
|
||
end;
|
||
cbTransforms.clear;
|
||
for i := 0 to Transforms - 1 do
|
||
cbTransforms.Items.Add(IntToStr(i + 1));
|
||
cbTransforms.ItemIndex := SelectedTriangle;
|
||
end;
|
||
end;
|
||
|
||
function InsideTriangle(x, y: double): integer;
|
||
var
|
||
i, j, k: integer;
|
||
inside: boolean;
|
||
begin
|
||
{ is x, y inside a triangle }
|
||
Result := -1;
|
||
inside := False;
|
||
j := 2;
|
||
for k := Transforms - 1 downto 0 do
|
||
begin
|
||
for i := 0 to 2 do
|
||
begin
|
||
if (((MainTriangles[k].y[i] <= y) and
|
||
(y < MainTriangles[k].y[j])) or
|
||
((MainTriangles[k].y[j] <= y) and
|
||
(y < MainTriangles[k].y[i]))) and
|
||
(x < (MainTriangles[k].x[j] - MainTriangles[k].x[i]) *
|
||
(y - MainTriangles[k].y[i]) /
|
||
(MainTriangles[k].y[j] - MainTriangles[k].y[i]) +
|
||
MainTriangles[k].x[i]) then
|
||
Inside := not Inside;
|
||
j := i
|
||
end;
|
||
if inside then break;
|
||
end;
|
||
if inside then Result := k;
|
||
end;
|
||
|
||
{
|
||
//used only one time - moved into procedure
|
||
procedure TEditForm.MouseInTriangle(fx, fy: double);
|
||
var
|
||
i, j: integer;
|
||
d: double;
|
||
begin
|
||
for i := 0 to Transforms - 1 do
|
||
for j := 0 to 2 do
|
||
begin
|
||
d := dist(fx, fy, MainTriangles[i].x[j], MainTriangles[i].y[j]);
|
||
if (d * GraphZoom * 50) < 4 then
|
||
begin
|
||
mouseOverTriangle:=i;
|
||
mouseOverCorner:=j;
|
||
exit;
|
||
end;
|
||
end;
|
||
|
||
i := InsideTriangle(fx, fy);
|
||
if i >= 0 then // i > -1
|
||
begin
|
||
mouseOverTriangle:=i;
|
||
end
|
||
else begin
|
||
mouseOverTriangle:=-2;
|
||
end;
|
||
mouseOverCorner:=-1;
|
||
end;
|
||
}
|
||
|
||
{
|
||
function TEditForm.InsideSelected(x, y: double): boolean;
|
||
var
|
||
i, j, k: integer;
|
||
inside: boolean;
|
||
begin
|
||
inside := False;
|
||
j := 2;
|
||
k := SelectedTriangle;
|
||
for i := 0 to 2 do
|
||
begin
|
||
if (((MainTriangles[k].y[i] <= y) and
|
||
(y < MainTriangles[k].y[j])) or
|
||
((MainTriangles[k].y[j] <= y) and
|
||
(y < MainTriangles[k].y[i]))) and
|
||
(x < (MainTriangles[k].x[j] - MainTriangles[k].x[i]) *
|
||
(y - MainTriangles[k].y[i]) /
|
||
(MainTriangles[k].y[j] - MainTriangles[k].y[i]) +
|
||
MainTriangles[k].x[i]) then inside := not inside;
|
||
j := i
|
||
end;
|
||
InsideSelected := inside;
|
||
end;
|
||
}
|
||
|
||
function TEditForm.GetTriangleColor(n: integer): TColor;
|
||
begin
|
||
if chkUseXFormColor.checked then
|
||
Result := ColorValToColor(MainCp.cmap, cp.xform[n].color)
|
||
else Result := clr[n mod 16];
|
||
end;
|
||
|
||
procedure TEditForm.DrawGraph;
|
||
var
|
||
i: integer;
|
||
ix, iy, sc: double;
|
||
ax, ay, bx, by, cx, cy: integer;
|
||
Width, Height: integer;
|
||
// BitMap: TBitMap;
|
||
// --Z--
|
||
gridX1, gridX2, gridY1, gridY2, gi, gstep: double;
|
||
gp: TRoundToRange;
|
||
label DrawCorner;
|
||
begin
|
||
// --Z-- hmmm:
|
||
if SelectedTriangle < 0 then SelectedTriangle := 0
|
||
else if SelectedTriangle >= Transforms then SelectedTriangle := Transforms-1;
|
||
|
||
// BitMap := TBitMap.Create;
|
||
try
|
||
Width := TriangleGraph.Width;
|
||
Height := TriangleGraph.Height;
|
||
// BitMap.Width := Width;
|
||
// BitMap.Height := Height;
|
||
ix := Width / 2;
|
||
iy := Height / 2;
|
||
sc := 50 * GraphZoom;
|
||
// with Bitmap.canvas do
|
||
with TriangleGraph.Canvas do
|
||
begin
|
||
brush.Color := pnlBackColor.Color;
|
||
FillRect(rect(0, 0, Width, Height));
|
||
|
||
Pen.Width := 1;
|
||
// --Z--
|
||
// draw grid
|
||
Pen.Style := psSolid;
|
||
Pen.Color := GridColor2;
|
||
gridX1:=gCenterX-ix/sc;
|
||
gridX2:=gCenterX+(Width-ix)/sc;
|
||
gridY1:=gCenterY-iy/sc;
|
||
gridY2:=gCenterY+(Height-iy)/sc;
|
||
try // who knows... ;)
|
||
gp:=round(log10(gridX2-gridX1));
|
||
if gp < log10(gridY2-gridY1) then gp:=round(log10(gridY2-gridY1));
|
||
Dec(gp);
|
||
gstep:=power(10.0, gp);
|
||
except
|
||
gp:=0;
|
||
gstep:=1.0;
|
||
end;
|
||
|
||
gi:=RoundTo(gridX1, gp);
|
||
while gi <= gridX2 do
|
||
begin
|
||
ax:=integer(round(ix + (gi - gCenterX)*sc));
|
||
MoveTo(ax, 0);
|
||
LineTo(ax, Height);
|
||
gi:=gi+gstep;
|
||
end;
|
||
gi:=RoundTo(gridY1, gp);
|
||
while gi <= gridY2 do
|
||
begin
|
||
ay:=integer(round(iy - (gi - gCenterY)*sc));
|
||
MoveTo(0, ay);
|
||
LineTo(Width, ay);
|
||
gi:=gi+gstep;
|
||
end;
|
||
// draw axis
|
||
Pen.Color := GridColor1;
|
||
Pen.Style := psSolid;
|
||
ax := integer(round(ix - gCenterX*sc));
|
||
ay := integer(round(iy + gCentery*sc));
|
||
MoveTo(ax, 0);
|
||
LineTo(ax, Height-1);
|
||
MoveTo(0, ay);
|
||
LineTo(Width-1, ay);
|
||
// --
|
||
|
||
{Reference Triangle}
|
||
Pen.Style := psDot;
|
||
Pen.color := pnlReference.Color;
|
||
ax := integer(round(ix + (MainTriangles[-1].x[0] - gCenterX) * sc));
|
||
ay := integer(round(iy - (MainTriangles[-1].y[0] - gCenterY) * sc));
|
||
bx := integer(round(ix + (MainTriangles[-1].x[1] - gCenterX) * sc));
|
||
by := integer(round(iy - (MainTriangles[-1].y[1] - gCenterY) * sc));
|
||
cx := integer(round(ix + (MainTriangles[-1].x[2] - gCenterX) * sc));
|
||
cy := integer(round(iy - (MainTriangles[-1].y[2] - gCenterY) * sc));
|
||
Polyline([Point(ax,ay), Point(bx,by), Point(cx,cy), Point(ax,ay)]);
|
||
Font.color := Pen.color;
|
||
TextOut(ax, ay, 'A');
|
||
TextOut(bx, by, 'B');
|
||
TextOut(cx, cy, 'C');
|
||
|
||
Pen.Style := psSolid;
|
||
|
||
{Transforms}
|
||
for i := 0 to Transforms - 1 do
|
||
begin
|
||
ax := integer(round(ix + (MainTriangles[i].x[0] - gCenterX) * sc));
|
||
ay := integer(round(iy - (MainTriangles[i].y[0] - gCenterY) * sc));
|
||
bx := integer(round(ix + (MainTriangles[i].x[1] - gCenterX) * sc));
|
||
by := integer(round(iy - (MainTriangles[i].y[1] - gCenterY) * sc));
|
||
cx := integer(round(ix + (MainTriangles[i].x[2] - gCenterX) * sc));
|
||
cy := integer(round(iy - (MainTriangles[i].y[2] - gCenterY) * sc));
|
||
{
|
||
TrgPoints[0].x := integer(round(ix + (MainTriangles[i].x[0] - gCenterX) * sc));
|
||
TrgPoints[0].y := integer(round(iy - (MainTriangles[i].y[0] - gCenterY) * sc));
|
||
TrgPoints[1].x := integer(round(ix + (MainTriangles[i].x[1] - gCenterX) * sc));
|
||
TrgPoints[1].y := integer(round(iy - (MainTriangles[i].y[1] - gCenterY) * sc));
|
||
TrgPoints[2].x := integer(round(ix + (MainTriangles[i].x[2] - gCenterX) * sc));
|
||
TrgPoints[2].y := integer(round(iy - (MainTriangles[i].y[2] - gCenterY) * sc));
|
||
}
|
||
//brush.Color := pnlBackColor.Color;
|
||
|
||
Pen.Color := GetTriangleColor(i);
|
||
|
||
if i <> SelectedTriangle then Pen.Style := psDot;
|
||
//MoveTo(ax, ay); LineTo(bx, by); LineTo(cx, cy); LineTo(ax, ay);
|
||
Polyline([Point(ax,ay), Point(bx,by), Point(cx,cy), Point(ax,ay)]);
|
||
|
||
Pen.Style := psSolid;
|
||
Ellipse(ax - 4, ay - 4, ax + 4, ay + 4);
|
||
Ellipse(bx - 4, by - 4, bx + 4, by + 4);
|
||
Ellipse(cx - 4, cy - 4, cx + 4, cy + 4);
|
||
|
||
Font.color := Pen.color;
|
||
//brush.Color := pnlBackColor.Color;
|
||
TextOut(ax, ay, 'A');
|
||
TextOut(bx, by, 'B');
|
||
TextOut(cx, cy, 'C');
|
||
{
|
||
brush.style:=bsClear;
|
||
Font.color := pnlBackColor.Color;
|
||
font.style:=[fsBold];
|
||
TextOut(ax+2, ay+2, 'A');
|
||
TextOut(bx+2, by+2, 'B');
|
||
TextOut(cx+2, cy+2, 'C');
|
||
font.style:=[];
|
||
|
||
Font.color := Pen.color;
|
||
TextOut(ax+1, ay+1, 'A');
|
||
TextOut(bx+1, by+1, 'B');
|
||
TextOut(cx+1, cy+1, 'C');
|
||
}
|
||
end;
|
||
|
||
// if dragging, draw pivot axis
|
||
if TriangleCaught or CornerCaught then
|
||
begin
|
||
Pen.Mode := pmMerge;
|
||
Pen.Color := $555555;
|
||
Pen.Style := psDot;
|
||
ax := integer(round(ix + (Pivot.x - gCenterX)*sc));
|
||
ay := integer(round(iy + (gCentery - Pivot.y)*sc));
|
||
MoveTo(ax, 0);
|
||
LineTo(ax, Height);
|
||
MoveTo(0, ay);
|
||
LineTo(Width, ay);
|
||
Pen.Color := $707070;
|
||
Pen.Style := psSolid;
|
||
Pen.Mode := pmXor;
|
||
if CornerCaught then
|
||
begin
|
||
ax := integer(round(ix + (MainTriangles[SelectedTriangle].x[SelectedCorner] - gCenterX)*sc));
|
||
ay := integer(round(iy - (MainTriangles[SelectedTriangle].y[SelectedCorner] - gCenterY)*sc));
|
||
end
|
||
else begin
|
||
ax := integer(round(ix + (GetPivot.x - gCenterX)*sc));
|
||
ay := integer(round(iy - (GetPivot.y - gCenterY)*sc));
|
||
end;
|
||
MoveTo(ax, 0);
|
||
LineTo(ax, Height);
|
||
MoveTo(0, ay);
|
||
LineTo(Width, ay);
|
||
Pen.Mode := pmCopy;
|
||
|
||
mouseOverTriangle := SelectedTriangle;
|
||
end;
|
||
|
||
if (mouseOverTriangle >= 0) then // highlight triangle under cursor
|
||
begin
|
||
ax := integer(round(ix + (MainTriangles[mouseOverTriangle].x[0] - gCenterX) * sc));
|
||
ay := integer(round(iy - (MainTriangles[mouseOverTriangle].y[0] - gCenterY) * sc));
|
||
bx := integer(round(ix + (MainTriangles[mouseOverTriangle].x[1] - gCenterX) * sc));
|
||
by := integer(round(iy - (MainTriangles[mouseOverTriangle].y[1] - gCenterY) * sc));
|
||
cx := integer(round(ix + (MainTriangles[mouseOverTriangle].x[2] - gCenterX) * sc));
|
||
cy := integer(round(iy - (MainTriangles[mouseOverTriangle].y[2] - gCenterY) * sc));
|
||
// Pen.Style:=psSolid;
|
||
pen.Width:=2;
|
||
Pen.Color:=GetTriangleColor(mouseOverTriangle) shr 1 and $7f7f7f;
|
||
Pen.Mode:=pmMerge;//pmXor;
|
||
brush.Color:=Pen.Color shr 1 and $7f7f7f;
|
||
//Polyline([Point(ax,ay), Point(bx,by), Point(cx,cy), Point(ax,ay)]);
|
||
Polygon([Point(ax,ay), Point(bx,by), Point(cx,cy)]);
|
||
pen.width:=4;
|
||
Ellipse(ax - 3, ay - 3, ax + 3, ay + 3);
|
||
Ellipse(bx - 3, by - 3, bx + 3, by + 3);
|
||
Ellipse(cx - 3, cy - 3, cx + 3, cy + 3);
|
||
pen.width:=1;
|
||
pen.mode:=pmCopy;
|
||
// brush.Color := pen.Color;
|
||
end;
|
||
|
||
pen.color := clWhite;
|
||
brush.Color:=clSilver;
|
||
if CornerCaught then // draw selected corner
|
||
begin
|
||
ax := integer(round(ix + (MainTriangles[SelectedTriangle].x[SelectedCorner] - gCenterX) * sc));
|
||
ay := integer(round(iy - (MainTriangles[SelectedTriangle].y[SelectedCorner] - gCenterY) * sc));
|
||
Ellipse(ax - 4, ay - 4, ax + 4, ay + 4);
|
||
end
|
||
else if (mouseOverTriangle>=0) and (mouseOverCorner >= 0) then // highlight corner under cursor
|
||
begin
|
||
// brush.Color := GetTriangleColor(mouseOverTriangle) shr 1 and $7f7f7f;
|
||
ax := integer(round(ix + (MainTriangles[mouseOverTriangle].x[mouseOverCorner] - gCenterX) * sc));
|
||
ay := integer(round(iy - (MainTriangles[mouseOverTriangle].y[mouseOverCorner] - gCenterY) * sc));
|
||
Ellipse(ax - 4, ay - 4, ax + 4, ay + 4);
|
||
end;
|
||
|
||
// draw pivot point
|
||
ax := integer(round(ix + (GetPivot.x - gCenterX) * sc));
|
||
ay := integer(round(iy - (GetPivot.y - gCenterY) * sc));
|
||
Pen.Style := psSolid;
|
||
pen.Color:=clWhite;
|
||
brush.Color:=clSilver;
|
||
Ellipse(ax - 2, ay - 2, ax + 2, ay + 2);
|
||
{
|
||
MoveTo(ax-3, ay);
|
||
LineTo(ax, ay-3);
|
||
LineTo(ax+3, ay);
|
||
LineTo(ax, ay+3);
|
||
LineTo(ax-3, ay);
|
||
}
|
||
// --
|
||
end;
|
||
// GraphImage.Picture.Graphic := Bitmap;
|
||
// GraphImage.Refresh;
|
||
finally
|
||
// BitMap.Free;
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.FormCreate(Sender: TObject);
|
||
var
|
||
i: integer;
|
||
begin
|
||
//
|
||
TriangleGraph := TTriangleGraph.Create(self);
|
||
TriangleGraph.TabStop := True;
|
||
TriangleGraph.Parent := GrphPnl;
|
||
TriangleGraph.Align := alClient;
|
||
TriangleGraph.Visible := True;
|
||
|
||
TriangleGraph.OnDblClick := GraphImageDblClick;
|
||
TriangleGraph.OnMouseDown := GraphImageMouseDown;
|
||
TriangleGraph.OnMouseMove := GraphImageMouseMove;
|
||
TriangleGraph.OnMouseUp := GraphImageMouseUp;
|
||
TriangleGraph.OnMouseWheel := EditMouseWheel;
|
||
TriangleGraph.OnKeyDown := EditKeyDown;
|
||
|
||
// TriangleGraph.PopupMenu := EditPopup;
|
||
// TriangleGraph.OnPaint :=
|
||
//
|
||
|
||
for i:= 0 to NRVAR - 1 do begin
|
||
VEVars.InsertRow(Varnames(i), '0', True);
|
||
end;
|
||
|
||
for i:= 0 to GetNrVariableNames - 1 do begin
|
||
vleVariables.InsertRow(GetVariableNameAt(i), '0', True);
|
||
end;
|
||
|
||
bm := TBitmap.Create;
|
||
GraphZoom := 1;
|
||
|
||
case EditPrevQual of
|
||
0: begin
|
||
mnuLowQuality.Checked := true;
|
||
PreviewDensity := prevLowQuality;
|
||
end;
|
||
1: begin
|
||
mnuMediumQuality.Checked := true;
|
||
PreviewDensity := prevMediumQuality;
|
||
end;
|
||
2: begin
|
||
mnuHighQuality.Checked := true;
|
||
PreviewDensity := prevHighQuality;
|
||
end;
|
||
end;
|
||
cp := TControlPoint.Create;
|
||
Render := TRenderer.Create;
|
||
|
||
SelectMode := true;
|
||
editMode := modeMove;
|
||
mouseOverTriangle := -1;
|
||
mouseOverCorner := -1;
|
||
|
||
for i := 0 to NRVAR-1 do
|
||
VarsCache[i] := MinDouble;
|
||
end;
|
||
|
||
procedure TEditForm.GraphImageMouseMove(Sender: TObject; Shift: TShiftState;
|
||
X, Y: integer);
|
||
var
|
||
vx, vy, fx, fy: double;
|
||
mt,mc: integer;
|
||
|
||
i, j: integer;
|
||
d: double;
|
||
label FoundCorner;
|
||
begin
|
||
Scale(fx, fy, x, y, TriangleGraph.Width, TriangleGraph.Height);
|
||
// --Z--
|
||
StatusBar.Panels[0].Text := Format('X: %f', [fx]);
|
||
StatusBar.Panels[1].Text := Format('Y: %f', [fy]);
|
||
|
||
mt:=mouseOverTriangle;
|
||
mc:=MouseOverCorner;
|
||
|
||
if SelectMode then // look for point or triangle under cursor
|
||
begin
|
||
for i := 0 to Transforms - 1 do
|
||
for j := 0 to 2 do
|
||
begin
|
||
d := dist(fx, fy, MainTriangles[i].x[j], MainTriangles[i].y[j]);
|
||
if (d * GraphZoom * 50) < 4 then
|
||
begin
|
||
mouseOverTriangle:=i;
|
||
mouseOverCorner:=j;
|
||
|
||
goto FoundCorner;
|
||
end;
|
||
end;
|
||
|
||
i := InsideTriangle(fx, fy);
|
||
if i >= 0 then // i > -1
|
||
begin
|
||
mouseOverTriangle:=i;
|
||
end
|
||
else begin
|
||
mouseOverTriangle:=-2;
|
||
end;
|
||
mouseOverCorner:=-1;
|
||
|
||
FoundCorner:
|
||
|
||
end; // if SelectMode
|
||
|
||
|
||
if (mouseOverTriangle >= 0) and (SelectMode or (mouseOverTriangle = SelectedTriangle)) then
|
||
TriangleGraph.Cursor := crHandPoint
|
||
else
|
||
TriangleGraph.Cursor := crArrow;
|
||
|
||
if graphDragMode then // graph panning
|
||
begin
|
||
dragged := true;
|
||
GcenterX := GcenterX - (fx - oldx);
|
||
GcenterY := GcenterY - (fy - oldy);
|
||
DrawGraph;
|
||
exit;
|
||
end;
|
||
|
||
Shift := Shift - [ssLeft];
|
||
|
||
if CornerCaught then
|
||
begin { Drag a corner }
|
||
// --Z--
|
||
if (Shift = [ssAlt]) or ((editMode = modeRotate) and (Shift = [])) then
|
||
begin // rotate point around pivot
|
||
vy := dist(Pivot.X, Pivot.Y, fx, fy);
|
||
if vy<>0 then begin
|
||
vx := (fx-Pivot.X)*olddist/vy;
|
||
vy := (fy-Pivot.Y)*olddist/vy;
|
||
end
|
||
else begin
|
||
vx := 0;
|
||
vy := 0;
|
||
end;
|
||
MainTriangles[SelectedTriangle].x[SelectedCorner] := Pivot.X+vx;
|
||
MainTriangles[SelectedTriangle].y[SelectedCorner] := Pivot.Y+vy;
|
||
vx:=arctan2(vy,vx);
|
||
vy:=arctan2(oldy,oldx);
|
||
StatusBar.Panels[2].Text := Format('Rotate: %3.2f<EFBFBD>', [(vx-vy)*180/PI]);
|
||
end
|
||
else if (Shift = [ssCtrl]) or ((editMode = modeScale) and (Shift = [])) then
|
||
begin // move point along vector
|
||
if olddist<>0 then begin
|
||
vy := (oldx*(fx-Pivot.X) + oldy*(fy-Pivot.Y))/(olddist*olddist);
|
||
MainTriangles[SelectedTriangle].x[SelectedCorner] := Pivot.X+oldx*vy;
|
||
MainTriangles[SelectedTriangle].y[SelectedCorner] := Pivot.Y+oldy*vy;
|
||
StatusBar.Panels[2].Text := Format('Scale: %3.2f%%', [vy*100]);
|
||
end
|
||
else begin
|
||
MainTriangles[SelectedTriangle].x[SelectedCorner] := Pivot.X;
|
||
MainTriangles[SelectedTriangle].y[SelectedCorner] := Pivot.Y;
|
||
end;
|
||
end
|
||
else begin // snap/move
|
||
if Shift = [ssShift] then // snap to axis
|
||
begin
|
||
if abs(fx-Pivot.X) > abs(fy-Pivot.Y) then begin
|
||
MainTriangles[SelectedTriangle].x[SelectedCorner] := fx;
|
||
MainTriangles[SelectedTriangle].y[SelectedCorner] := Pivot.Y;
|
||
end
|
||
else begin
|
||
MainTriangles[SelectedTriangle].x[SelectedCorner] := Pivot.x;
|
||
MainTriangles[SelectedTriangle].y[SelectedCorner] := fy;
|
||
end;
|
||
end
|
||
else begin // just move
|
||
MainTriangles[SelectedTriangle].x[SelectedCorner] := fx;
|
||
MainTriangles[SelectedTriangle].y[SelectedCorner] := fy;
|
||
end;
|
||
StatusBar.Panels[2].Text := Format('Move: %3.3f ; %3.3f', [fx-(Pivot.X+oldx), fy-(Pivot.Y+oldy)]);
|
||
end;
|
||
// --
|
||
HasChanged := True;
|
||
UpdateFlameX;
|
||
// UpdateFlame(False);
|
||
StatusBar.Refresh;
|
||
exit;
|
||
end
|
||
else if TriangleCaught then { Modify a whole triangle }
|
||
begin
|
||
if (Shift = [ssAlt]) or ((editMode = modeRotate) and (Shift = [])) then // rotate
|
||
begin
|
||
vy := arctan2(oldy, oldx);
|
||
vx := arctan2(fy-Pivot.Y, fx-Pivot.X);
|
||
MainTriangles[SelectedTriangle] :=
|
||
RotateTrianglePoint(OldTriangle, Pivot.X, Pivot.Y, vx-vy);
|
||
StatusBar.Panels[2].Text := Format('Rotate: %3.2f<EFBFBD>', [(vx-vy)*180/PI]);
|
||
end
|
||
else if (Shift = [ssCtrl]) or ((editMode = modeScale) and (Shift = [])) then
|
||
begin // scale
|
||
if olddist<>0 then begin
|
||
vy := (oldx*(fx-Pivot.X) + oldy*(fy-Pivot.Y))/(olddist*olddist);
|
||
MainTriangles[SelectedTriangle] :=
|
||
ScaleTrianglePoint(OldTriangle, Pivot.X, Pivot.Y, vy);
|
||
StatusBar.Panels[2].Text := Format('Scale: %3.2f%%', [vy*100]);
|
||
end
|
||
else MainTriangles[SelectedTriangle] := OldTriangle;
|
||
end
|
||
else begin // snap/move
|
||
vx := fx - (Pivot.x + oldx);
|
||
vy := fy - (Pivot.y + oldy);
|
||
if Shift = [ssShift] then // snap to axis
|
||
begin
|
||
//if abs(fx - Pivot.X) > abs(fy - Pivot.Y) then vy := 0
|
||
if abs(vx) > abs(vy) then vy := 0
|
||
else vx := 0;
|
||
end;
|
||
MainTriangles[SelectedTriangle].x[0] := OldTriangle.x[0] + vx;
|
||
MainTriangles[SelectedTriangle].y[0] := OldTriangle.y[0] + vy;
|
||
MainTriangles[SelectedTriangle].x[1] := OldTriangle.x[1] + vx;
|
||
MainTriangles[SelectedTriangle].y[1] := OldTriangle.y[1] + vy;
|
||
MainTriangles[SelectedTriangle].x[2] := OldTriangle.x[2] + vx;
|
||
MainTriangles[SelectedTriangle].y[2] := OldTriangle.y[2] + vy;
|
||
StatusBar.Panels[2].Text := Format('Move: %3.3f ; %3.3f', [vx, vy]);
|
||
end;
|
||
HasChanged := True;
|
||
UpdateFlameX;
|
||
// UpdateFlame(False);
|
||
StatusBar.Refresh;
|
||
exit;
|
||
end;
|
||
if ((mt <> mouseOverTriangle) or (mc <> MouseOverCorner)) then
|
||
begin
|
||
if (mouseOverTriangle >= 0) then
|
||
StatusBar.Panels[2].Text := Format('Transform #%d', [mouseOverTriangle+1])
|
||
else StatusBar.Panels[2].Text := '';
|
||
DrawGraph;
|
||
end
|
||
end;
|
||
|
||
procedure TEditForm.GraphImageMouseDown(Sender: TObject; Button: TMouseButton;
|
||
Shift: TShiftState; X, Y: integer);
|
||
var
|
||
d, fx, fy: double;
|
||
i, j: integer;
|
||
//label GotCorner;
|
||
begin
|
||
// intoldx := x;
|
||
// intoldy := y;
|
||
CornerCaught := False;
|
||
TriangleCaught := False;
|
||
dragged := false; // --Z--
|
||
Scale(fx, fy, x, y, TriangleGraph.Width, TriangleGraph.Height);
|
||
Shift := Shift - [ssLeft]; // --Z--
|
||
if Button = mbLeft then
|
||
begin
|
||
if SelectMode = false then // Only change the selected triangle
|
||
begin
|
||
{Has user grabbed a corner?}
|
||
for j := 0 to 2 do
|
||
begin
|
||
d := dist(fx, fy, MainTriangles[SelectedTriangle].x[j], MainTriangles[SelectedTriangle].y[j]);
|
||
if (d * GraphZoom * 50) < 4 then begin//goto GotCorner;
|
||
// WTF!?! goto isn't working right way in this shitty pascal!!! 8-()
|
||
SelectedCorner := j;
|
||
Pivot := GetPivot;
|
||
oldx := MainTriangles[SelectedTriangle].x[j] - Pivot.X;
|
||
oldy := MainTriangles[SelectedTriangle].y[j] - Pivot.Y;
|
||
olddist := sqrt(oldx*oldx + oldy*oldy);
|
||
|
||
MainForm.UpdateUndo;
|
||
CornerCaught := True;
|
||
DrawPreview;
|
||
ShowSelectedInfo;
|
||
DrawGraph;
|
||
exit;
|
||
//
|
||
end;
|
||
end;
|
||
end
|
||
else begin // Find a corner and select triangle
|
||
for i := Transforms - 1 downto 0 do
|
||
for j := 0 to 2 do
|
||
begin
|
||
d := dist(fx, fy, MainTriangles[i].x[j], MainTriangles[i].y[j]);
|
||
if (d * GraphZoom * 50) < 4 then
|
||
begin
|
||
SelectedTriangle := i;
|
||
//GotCorner:
|
||
SelectedCorner := j;
|
||
Pivot := GetPivot;
|
||
oldx := MainTriangles[SelectedTriangle].x[j] - Pivot.X;
|
||
oldy := MainTriangles[SelectedTriangle].y[j] - Pivot.Y;
|
||
olddist := sqrt(oldx*oldx + oldy*oldy);
|
||
|
||
MainForm.UpdateUndo;
|
||
CornerCaught := True;
|
||
DrawPreview;
|
||
ShowSelectedInfo;
|
||
DrawGraph;
|
||
exit;
|
||
end;
|
||
end;
|
||
end;
|
||
// so user hasn't selected any corners,
|
||
// let's check for triangles then!
|
||
|
||
// --Z-- // alt=rotate, ctrl=scale, shift=move
|
||
|
||
if SelectMode then
|
||
begin
|
||
i := InsideTriangle(fx, fy);
|
||
if i >= 0 then SelectedTriangle := i
|
||
else
|
||
if Shift * [ssAlt,ssCtrl,ssShift] = [] then exit;
|
||
end;
|
||
|
||
OldTriangle := MainTriangles[SelectedTriangle];
|
||
MainForm.UpdateUndo;
|
||
TriangleCaught := True;
|
||
|
||
Pivot := GetPivot;
|
||
oldx := fx-Pivot.X;
|
||
oldy := fy-Pivot.Y;
|
||
olddist := sqrt(oldx*oldx + oldy*oldy);
|
||
|
||
DrawPreview;
|
||
ShowSelectedInfo;
|
||
DrawGraph;
|
||
exit;
|
||
end
|
||
else if Button = mbRight then // graph panning
|
||
begin
|
||
SetCaptureControl(TriangleGraph);
|
||
Screen.Cursor := crSizeAll;
|
||
|
||
graphDragMode := true;
|
||
oldx := fx;
|
||
oldY := fy;
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.GraphImageMouseUp(Sender: TObject; Button: TMouseButton;
|
||
Shift: TShiftState; X, Y: integer);
|
||
begin
|
||
if Button = mbRight then // --Z-- panning
|
||
begin
|
||
graphDragMode := false;
|
||
if dragged=false then // haven't dragged - popup menu then
|
||
begin
|
||
GetCursorPos(mousepos); // hmmm
|
||
EditPopup.Popup(mousepos.x, mousepos.y);
|
||
end
|
||
else dragged := false;
|
||
Screen.Cursor := crDefault;
|
||
SetCaptureControl(nil);
|
||
exit;
|
||
end;
|
||
|
||
CornerCaught := False;
|
||
TriangleCaught := False;
|
||
if HasChanged then
|
||
begin
|
||
UpdateFlame(true);
|
||
HasChanged := False;
|
||
end
|
||
else DrawGraph;
|
||
end;
|
||
|
||
{
|
||
procedure TEditForm.mnuRotateRightClick(Sender: TObject);
|
||
var
|
||
offset: double;
|
||
begin
|
||
try
|
||
offset := StrToFloat(txtTrgRotateValue.Text);
|
||
except
|
||
offset := 0;
|
||
txtTrgRotateValue.Text := '0';
|
||
end;
|
||
if offset <> 0 then
|
||
begin
|
||
MainTriangles[SelectedTriangle] := RotateTriangleCenter(MainTriangles[SelectedTriangle], -((PI/180) * offset));
|
||
HasChanged := True;
|
||
UpdateFlame(true);
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.mnuRotateLeftClick(Sender: TObject);
|
||
var
|
||
offset: double;
|
||
begin
|
||
try
|
||
offset := StrToFloat(txtTrgRotateValue.Text);
|
||
except
|
||
offset := 0;
|
||
txtTrgRotateValue.Text := '0';
|
||
end;
|
||
if offset <> 0 then
|
||
begin
|
||
MainTriangles[SelectedTriangle] := RotateTriangleCenter(MainTriangles[SelectedTriangle], (PI/180) * offset);
|
||
HasChanged := True;
|
||
UpdateFlame(true);
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.mnuScaleUpClick(Sender: TObject);
|
||
var
|
||
scale: double;
|
||
begin
|
||
try
|
||
scale := StrToFloat(txtTrgScaleValue.Text);
|
||
except
|
||
scale := 0.0;
|
||
txtTrgScaleValue.Text := '0.0';
|
||
end;
|
||
if scale <> 0 then
|
||
begin
|
||
MainTriangles[SelectedTriangle] := ScaleTriangleCenter(MainTriangles[SelectedTriangle], scale+1.0);
|
||
HasChanged := True;
|
||
UpdateFlame(true);
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.mnuScaleDownClick(Sender: TObject);
|
||
var
|
||
scale: double;
|
||
begin
|
||
try
|
||
scale := StrToFloat(txtTrgScaleValue.Text);
|
||
except
|
||
scale := 0.0;
|
||
txtTrgScaleValue.Text := '0.0';
|
||
end;
|
||
if scale <> 0 then
|
||
begin
|
||
MainTriangles[SelectedTriangle] := ScaleTriangleCenter(MainTriangles[SelectedTriangle], 1.0-scale);
|
||
HasChanged := True;
|
||
UpdateFlame(true);
|
||
end;
|
||
end;
|
||
}
|
||
|
||
procedure TEditForm.FormShow(Sender: TObject);
|
||
var
|
||
Registry: TRegistry;
|
||
begin
|
||
Registry := TRegistry.Create;
|
||
try
|
||
Registry.RootKey := HKEY_CURRENT_USER;
|
||
if Registry.OpenKey('Software\' + APP_NAME + '\Forms\Editor', False) then
|
||
begin
|
||
{ Size and position }
|
||
if Registry.ValueExists('Left') then
|
||
EditForm.Left := Registry.ReadInteger('Left');
|
||
if Registry.ValueExists('Top') then
|
||
EditForm.Top := Registry.ReadInteger('Top');
|
||
if Registry.ValueExists('Width') then
|
||
EditForm.Width := Registry.ReadInteger('Width');
|
||
if Registry.ValueExists('Height') then
|
||
EditForm.Height := Registry.ReadInteger('Height');
|
||
{ Options }
|
||
if Registry.ValueExists('UseTransformColors') then
|
||
begin
|
||
UseTransformColors := Registry.ReadBool('UseTransformColors');
|
||
end
|
||
else
|
||
begin
|
||
UseTransformColors := False;
|
||
end;
|
||
if Registry.ValueExists('UseFlameBackground') then
|
||
begin
|
||
UseFlameBackground := Registry.ReadBool('UseFlameBackground');
|
||
end
|
||
else
|
||
begin
|
||
UseFlameBackground := False;
|
||
end;
|
||
if Registry.ValueExists('BackgroundColor') then
|
||
BackgroundColor := Registry.ReadInteger('BackgroundColor')
|
||
else
|
||
BackgroundColor := integer(clBlack);
|
||
if Registry.ValueExists('GridColor1') then
|
||
GridColor1 := Registry.ReadInteger('GridColor1')
|
||
else
|
||
GridColor1 := $444444;
|
||
if Registry.ValueExists('GridColor2') then
|
||
GridColor2 := Registry.ReadInteger('GridColor2')
|
||
else
|
||
GridColor2 := $333333;
|
||
if Registry.ValueExists('ReferenceTriangleColor') then
|
||
ReferenceTriangleColor := Registry.ReadInteger('ReferenceTriangleColor')
|
||
else
|
||
ReferenceTriangleColor := integer(clGray);
|
||
if Registry.ValueExists('ResetLocation') then
|
||
mnuResetLoc.checked := Registry.ReadBool('ResetLocation')
|
||
else mnuResetLoc.checked := true;
|
||
tbResetLoc.Down := mnuResetLoc.checked;
|
||
end
|
||
else begin
|
||
UseTransformColors := False;
|
||
UseFlameBackground := False;
|
||
BackgroundColor := $000000;
|
||
GridColor1 := $444444;
|
||
GridColor2 := $333333;
|
||
ReferenceTriangleColor := integer(clGray);
|
||
mnuResetLoc.checked := true;
|
||
tbResetLoc.Down := true;
|
||
end;
|
||
Registry.CloseKey;
|
||
finally
|
||
Registry.Free;
|
||
end;
|
||
chkUseXFormColor.checked := UseTransformColors;
|
||
chkFlameBack.checked := UseFlameBackground;
|
||
pnlBackColor.Color := TColor(BackgroundColor);
|
||
GrphPnl.Color := TColor(BackgroundColor);
|
||
pnlGridColor1.Color := GridColor1;
|
||
pnlGridColor2.Color := GridColor2;
|
||
pnlReference.color := TColor(ReferenceTriangleColor);
|
||
UpdateDisplay;
|
||
end;
|
||
|
||
procedure TEditForm.mnuDeleteClick(Sender: TObject);
|
||
begin
|
||
if SelectedTriangle > -1 then DeleteTriangle(SelectedTriangle);
|
||
end;
|
||
|
||
procedure TEditForm.mnuAddClick(Sender: TObject);
|
||
var
|
||
i: integer;
|
||
begin
|
||
if Transforms < NXFORMS then
|
||
begin
|
||
MainForm.UpdateUndo;
|
||
Transforms := Transforms + 1;
|
||
MainTriangles[Transforms - 1] := MainTriangles[-1];
|
||
SelectedTriangle := Transforms - 1;
|
||
ComputeWeights(cp, MainTriangles, transforms);
|
||
cp.xform[Transforms - 1].vars[0] := 1;
|
||
for i := 1 to NRVAR - 1 do
|
||
cp.xform[Transforms - 1].vars[i] := 0;
|
||
cbTransforms.clear;
|
||
for i := 0 to Transforms - 1 do
|
||
cbTransforms.Items.Add(IntToStr(i + 1));
|
||
UpdateFlame(True);
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.mnuDupClick(Sender: TObject);
|
||
var
|
||
i: integer;
|
||
begin
|
||
if Transforms < NXFORMS then
|
||
begin
|
||
MainForm.UpdateUndo;
|
||
Transforms := Transforms + 1;
|
||
MainTriangles[Transforms - 1] := MainTriangles[SelectedTriangle];
|
||
ComputeWeights(cp, MainTriangles, transforms);
|
||
for i := 0 to NRVAR - 1 do
|
||
cp.xform[Transforms - 1].vars[i] := cp.xform[SelectedTriangle].vars[i];
|
||
SelectedTriangle := Transforms - 1;
|
||
cbTransforms.clear;
|
||
for i := 0 to Transforms - 1 do
|
||
cbTransforms.Items.Add(IntToStr(i + 1));
|
||
UpdateFlame(True);
|
||
end;
|
||
end;
|
||
|
||
|
||
procedure TEditForm.mnuAutoZoomClick(Sender: TObject);
|
||
begin
|
||
AutoZoom;
|
||
DrawGraph;
|
||
end;
|
||
{
|
||
procedure TEditForm.mnuXFlipClick(Sender: TObject);
|
||
begin
|
||
// MainTriangles[SelectedTriangle] := FlipTriangleHorizontal(MainTriangles[SelectedTriangle]);
|
||
with MainTriangles[SelectedTriangle] do // --Z--
|
||
begin
|
||
x[0] := GetPivot.x - x[0];
|
||
x[1] := x[1];
|
||
x[2] := x[2];
|
||
end;
|
||
UpdateFlame(True);
|
||
end;
|
||
|
||
procedure TEditForm.mnuYFlipClick(Sender: TObject);
|
||
begin
|
||
MainTriangles[SelectedTriangle] := FlipTriangleVertical(MainTriangles[SelectedTriangle]);
|
||
UpdateFlame(True);
|
||
end;
|
||
}
|
||
|
||
procedure TEditForm.btnCloseClick(Sender: TObject);
|
||
begin
|
||
EditForm.Close;
|
||
end;
|
||
|
||
procedure TEditForm.FormResize(Sender: TObject);
|
||
begin
|
||
Autozoom;
|
||
DrawGraph;
|
||
end;
|
||
|
||
procedure TEditForm.CornerEditExit(Sender: TObject);
|
||
var
|
||
Allow: boolean;
|
||
OldText: string;
|
||
Val: string;
|
||
begin
|
||
Allow := True;
|
||
if Sender = txtAx then
|
||
Val := Format('%.6f', [MainTriangles[SelectedTriangle].x[0]])
|
||
else if Sender = txtAy then
|
||
Val := Format('%.6f', [MainTriangles[SelectedTriangle].y[0]])
|
||
else if Sender = txtBx then
|
||
Val := Format('%.6f', [MainTriangles[SelectedTriangle].x[1]])
|
||
else if Sender = txtBy then
|
||
Val := Format('%.6f', [MainTriangles[SelectedTriangle].y[1]])
|
||
else if Sender = txtCx then
|
||
Val := Format('%.6f', [MainTriangles[SelectedTriangle].x[2]])
|
||
else if Sender = txtCy then
|
||
Val := Format('%.6f', [MainTriangles[SelectedTriangle].y[2]])
|
||
else if Sender = txtP then ;
|
||
val := Format('%.6f', [cp.xform[SelectedTriangle].density]);
|
||
OldText := Val;
|
||
{ Test that it's a valid floating point number }
|
||
try
|
||
StrToFloat(TEdit(Sender).Text);
|
||
except on Exception do
|
||
begin
|
||
{ It's not, so we restore the old value }
|
||
TEdit(Sender).Text := OldText;
|
||
Allow := False;
|
||
end;
|
||
end;
|
||
{ If it's not the same as the old value and it was valid }
|
||
if (val <> TEdit(Sender).Text) and Allow then
|
||
begin
|
||
if Sender = txtAx then
|
||
MainTriangles[SelectedTriangle].x[0] := StrToFloat(TEdit(Sender).Text)
|
||
else if Sender = txtAy then
|
||
MainTriangles[SelectedTriangle].y[0] := StrToFloat(TEdit(Sender).Text)
|
||
else if Sender = txtBx then
|
||
MainTriangles[SelectedTriangle].x[1] := StrToFloat(TEdit(Sender).Text)
|
||
else if Sender = txtBy then
|
||
MainTriangles[SelectedTriangle].y[1] := StrToFloat(TEdit(Sender).Text)
|
||
else if Sender = txtCx then
|
||
MainTriangles[SelectedTriangle].x[2] := StrToFloat(TEdit(Sender).Text)
|
||
else if Sender = txtCy then
|
||
MainTriangles[SelectedTriangle].y[2] := StrToFloat(TEdit(Sender).Text)
|
||
else if Sender = txtP then
|
||
begin
|
||
cp.xform[SelectedTriangle].density := StrToFloat(TEdit(Sender).Text);
|
||
ReadjustWeights(cp);
|
||
TEdit(Sender).Text := Format('%.6g', [cp.xform[SelectedTriangle].density]);
|
||
end;
|
||
MainForm.UpdateUndo;
|
||
UpdateFlame(True);
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.CornerEditKeyPress(Sender: TObject; var Key: Char);
|
||
var
|
||
Allow: boolean;
|
||
OldText: string;
|
||
Val: string;
|
||
begin
|
||
if key = #13 then
|
||
begin
|
||
Allow := True;
|
||
if Sender = txtAx then
|
||
Val := Format('%.6f', [MainTriangles[SelectedTriangle].x[0]])
|
||
else if Sender = txtAy then
|
||
Val := Format('%.6f', [MainTriangles[SelectedTriangle].y[0]])
|
||
else if Sender = txtBx then
|
||
Val := Format('%.6f', [MainTriangles[SelectedTriangle].x[1]])
|
||
else if Sender = txtBy then
|
||
Val := Format('%.6f', [MainTriangles[SelectedTriangle].y[1]])
|
||
else if Sender = txtCx then
|
||
Val := Format('%.6f', [MainTriangles[SelectedTriangle].x[2]])
|
||
else if Sender = txtCy then
|
||
Val := Format('%.6f', [MainTriangles[SelectedTriangle].y[2]])
|
||
else if Sender = txtP then ;
|
||
val := Format('%.6f', [cp.xform[SelectedTriangle].density]);
|
||
OldText := Val;
|
||
{ Stop the beep }
|
||
Key := #0;
|
||
{ Test that it's a valid floating point number }
|
||
try
|
||
StrToFloat(TEdit(Sender).Text);
|
||
except on Exception do
|
||
begin
|
||
{ It's not, so we restore the old value }
|
||
TEdit(Sender).Text := OldText;
|
||
Allow := False;
|
||
end;
|
||
end;
|
||
{ If it's not the same as the old value and it was valid }
|
||
if (val <> TEdit(Sender).Text) and Allow then
|
||
begin
|
||
if Sender = txtAx then
|
||
MainTriangles[SelectedTriangle].x[0] := StrToFloat(TEdit(Sender).Text)
|
||
else if Sender = txtAy then
|
||
MainTriangles[SelectedTriangle].y[0] := StrToFloat(TEdit(Sender).Text)
|
||
else if Sender = txtBx then
|
||
MainTriangles[SelectedTriangle].x[1] := StrToFloat(TEdit(Sender).Text)
|
||
else if Sender = txtBy then
|
||
MainTriangles[SelectedTriangle].y[1] := StrToFloat(TEdit(Sender).Text)
|
||
else if Sender = txtCx then
|
||
MainTriangles[SelectedTriangle].x[2] := StrToFloat(TEdit(Sender).Text)
|
||
else if Sender = txtCy then
|
||
MainTriangles[SelectedTriangle].y[2] := StrToFloat(TEdit(Sender).Text)
|
||
else if Sender = txtP then
|
||
begin
|
||
cp.xform[SelectedTriangle].density := StrToFloat(TEdit(Sender).Text);
|
||
ReadjustWeights(cp);
|
||
TEdit(Sender).Text := Format('%.6g', [cp.xform[SelectedTriangle].density]);
|
||
end;
|
||
MainForm.UpdateUndo;
|
||
UpdateFlame(True);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
{ ************************* Probability input ******************************** }
|
||
|
||
procedure TEditForm.txtPKeyPress(Sender: TObject; var Key: Char);
|
||
var
|
||
Allow: boolean;
|
||
NewVal, OldVal: double;
|
||
begin
|
||
if key = #13 then
|
||
begin
|
||
{ Stop the beep }
|
||
Key := #0;
|
||
Allow := True;
|
||
OldVal := Round6(cp.xform[SelectedTriangle].density);
|
||
{ Test that it's a valid floating point number }
|
||
try
|
||
StrToFloat(TEdit(Sender).Text);
|
||
except on Exception do
|
||
begin
|
||
{ It's not, so we restore the old value }
|
||
TEdit(Sender).Text := Format('%.6g', [OldVal]);
|
||
Allow := False;
|
||
end;
|
||
end;
|
||
NewVal := Round6(StrToFloat(TEdit(Sender).Text));
|
||
if NewVal < 0 then NewVal := 0;
|
||
if NewVal > 0.99 then NewVal := 0.99;
|
||
{ If it's not the same as the old value and it was valid }
|
||
TEdit(Sender).Text := Format('%.6g', [NewVal]);
|
||
if (OldVal <> NewVal) and Allow then
|
||
begin
|
||
MainForm.UpdateUndo;
|
||
cp.xform[SelectedTriangle].density := NewVal;
|
||
ReadjustWeights(cp);
|
||
UpdateFlame(True);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.txtPExit(Sender: TObject);
|
||
var
|
||
Allow: boolean;
|
||
NewVal, OldVal: double;
|
||
begin
|
||
Allow := True;
|
||
OldVal := Round6(cp.xform[SelectedTriangle].density);
|
||
{ Test that it's a valid floating point number }
|
||
try
|
||
StrToFloat(TEdit(Sender).Text);
|
||
except on Exception do
|
||
begin
|
||
{ It's not, so we restore the old value }
|
||
TEdit(Sender).Text := Format('%.6g', [OldVal]);
|
||
Allow := False;
|
||
end;
|
||
end;
|
||
NewVal := Round6(StrToFloat(TEdit(Sender).Text));
|
||
if NewVal < 0 then NewVal := 0;
|
||
if NewVal > 0.99 then NewVal := 0.99;
|
||
{ If it's not the same as the old value and it was valid }
|
||
TEdit(Sender).Text := Format('%.6g', [NewVal]);
|
||
if (OldVal <> NewVal) and Allow then
|
||
begin
|
||
MainForm.UpdateUndo;
|
||
cp.xform[SelectedTriangle].density := NewVal;
|
||
ReadjustWeights(cp);
|
||
UpdateFlame(True);
|
||
end;
|
||
end;
|
||
|
||
{ **************************************************************************** }
|
||
|
||
procedure TEditForm.FormClose(Sender: TObject; var Action: TCloseAction);
|
||
var
|
||
Registry: TRegistry;
|
||
begin
|
||
{ Write position to registry }
|
||
Registry := TRegistry.Create;
|
||
try
|
||
Registry.RootKey := HKEY_CURRENT_USER;
|
||
{ Defaults }
|
||
if Registry.OpenKey('\Software\' + APP_NAME + '\Forms\Editor', True) then
|
||
begin
|
||
{ Options }
|
||
Registry.WriteBool('UseTransformColors', UseTransformColors);
|
||
Registry.WriteBool('UseFlameBackground', UseFlameBackground);
|
||
Registry.WriteInteger('BackgroundColor', BackgroundColor);
|
||
Registry.WriteInteger('GridColor1', GridColor1);
|
||
Registry.WriteInteger('GridColor2', GridColor2);
|
||
Registry.WriteInteger('ReferenceTriangleColor', ReferenceTriangleColor);
|
||
Registry.WriteBool('ResetLocation', mnuResetLoc.checked);
|
||
{ Size and position }
|
||
if EditForm.WindowState <> wsMaximized then begin
|
||
Registry.WriteInteger('Top', EditForm.Top);
|
||
Registry.WriteInteger('Left', EditForm.Left);
|
||
Registry.WriteInteger('Width', EditForm.Width);
|
||
Registry.WriteInteger('Height', EditForm.Height);
|
||
end;
|
||
end;
|
||
finally
|
||
Registry.Free;
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.mnuUndoClick(Sender: TObject);
|
||
begin
|
||
MainForm.Undo;
|
||
end;
|
||
|
||
procedure TEditForm.mnuRedoClick(Sender: TObject);
|
||
begin
|
||
MainForm.Redo;
|
||
end;
|
||
|
||
procedure TEditForm.FormDestroy(Sender: TObject);
|
||
begin
|
||
bm.free;
|
||
cp.free;
|
||
Render.free;
|
||
end;
|
||
|
||
procedure TEditForm.mnuLowQualityClick(Sender: TObject);
|
||
begin
|
||
mnuLowQuality.Checked := True;
|
||
tbLowQ.Down := true;
|
||
PreviewDensity := prevLowQuality;
|
||
EditPrevQual := 0;
|
||
DrawPreview;
|
||
end;
|
||
|
||
procedure TEditForm.mnuHighQualityClick(Sender: TObject);
|
||
begin
|
||
mnuHighQuality.Checked := True;
|
||
tbHiQ.Down := true;
|
||
PreviewDensity := prevHighQuality;
|
||
EditPrevQual := 2;
|
||
DrawPreview;
|
||
end;
|
||
|
||
procedure TEditForm.mnuMediumQualityClick(Sender: TObject);
|
||
begin
|
||
mnuMediumQuality.Checked := True;
|
||
tbMedQ.Down := true;
|
||
PreviewDensity := prevMediumQuality;
|
||
EditPrevQual := 1;
|
||
DrawPreview;
|
||
end;
|
||
|
||
procedure TEditForm.mnuResetLocClick(Sender: TObject);
|
||
var
|
||
reset: boolean;
|
||
begin
|
||
reset:= not mnuResetLoc.Checked;
|
||
mnuResetLoc.Checked := reset;
|
||
tbResetLoc.Down := reset;
|
||
if reset then
|
||
begin
|
||
cp.width := MainCp.width;
|
||
cp.height := MainCp.height;
|
||
cp.pixels_per_unit := MainCp.pixels_per_unit;
|
||
AdjustScale(cp, PreviewImage.width, PreviewImage.Height);
|
||
cp.zoom := MainCp.zoom;
|
||
cp.center[0] := MainCp.center[0];
|
||
cp.center[1] := MainCp.center[1];
|
||
end;
|
||
DrawPreview;
|
||
end;
|
||
|
||
procedure TEditForm.mnuVerticalFlipAllClick(Sender: TObject);
|
||
var
|
||
i: integer;
|
||
begin
|
||
MainForm.UpdateUndo;
|
||
for i := -1 to Transforms - 1 do
|
||
begin
|
||
MainTriangles[i] := FlipTriangleVertical(MainTriangles[i]);
|
||
end;
|
||
AutoZoom;
|
||
UpdateFlame(True);
|
||
end;
|
||
|
||
procedure TEditForm.mnuHorizintalFlipAllClick(Sender: TObject);
|
||
var
|
||
i: integer;
|
||
begin
|
||
MainForm.UpdateUndo;
|
||
for i := -1 to Transforms - 1 do
|
||
begin
|
||
MainTriangles[i] := FlipTriangleHorizontal(MainTriangles[i]);
|
||
end;
|
||
AutoZoom;
|
||
UpdateFlame(True);
|
||
end;
|
||
|
||
procedure TEditForm.mnuFlipVerticalClick(Sender: TObject);
|
||
var
|
||
p: double;
|
||
begin
|
||
MainForm.UpdateUndo;
|
||
// MainTriangles[SelectedTriangle] := FlipTriangleVertical(MainTriangles[SelectedTriangle]);
|
||
with MainTriangles[SelectedTriangle] do // --Z--
|
||
begin
|
||
p := GetPivot.y * 2;
|
||
y[0] := p - y[0];
|
||
y[1] := p - y[1];
|
||
y[2] := p - y[2];
|
||
end;
|
||
AutoZoom;
|
||
UpdateFlame(True);
|
||
end;
|
||
|
||
procedure TEditForm.mnuFlipHorizontalClick(Sender: TObject);
|
||
var
|
||
p: double;
|
||
begin
|
||
MainForm.UpdateUndo;
|
||
// MainTriangles[SelectedTriangle] := FlipTriangleHorizontal(MainTriangles[SelectedTriangle]);
|
||
with MainTriangles[SelectedTriangle] do // --Z--
|
||
begin
|
||
p := GetPivot.x * 2;
|
||
x[0] := p - x[0];
|
||
x[1] := p - x[1];
|
||
x[2] := p - x[2];
|
||
end;
|
||
AutoZoom;
|
||
UpdateFlame(True);
|
||
end;
|
||
|
||
procedure TEditForm.GraphImageDblClick(Sender: TObject);
|
||
begin
|
||
AutoZoom;
|
||
DrawGraph;
|
||
end;
|
||
|
||
procedure TEditForm.cbTransformsChange(Sender: TObject);
|
||
begin
|
||
if SelectedTriangle <> cbTransforms.ItemIndex then SelectedTriangle := cbTransforms.ItemIndex;
|
||
ShowSelectedInfo;
|
||
DrawGraph;
|
||
end;
|
||
|
||
procedure TEditForm.cbTransformsDrawItem(Control: TWinControl;
|
||
Index: Integer; Rect: TRect; State: TOwnerDrawState);
|
||
var
|
||
h: integer;
|
||
ax,ay,bx,by: integer;
|
||
TrgColor: TColor;
|
||
begin
|
||
TrgColor := GetTriangleColor(Index);
|
||
with cbTransforms.Canvas do
|
||
begin
|
||
h := Rect.Bottom - Rect.Top;
|
||
|
||
brush.Color:=clBlack;
|
||
FillRect(Rect);
|
||
|
||
Font.Color := clWhite;
|
||
//TextOut(Rect.Left+h+2, Rect.Top, eqListBox.Items[Index]);
|
||
TextOut(Rect.Left+h+2, Rect.Top, IntToStr(Index+1)); // hack
|
||
|
||
pen.Color := TrgColor;
|
||
brush.Color := pen.Color shr 1 and $7f7f7f;
|
||
//pen.Style := psClear;
|
||
|
||
ax:=Rect.Left+h-2;
|
||
ay:=Rect.Top+1;
|
||
bx:=Rect.Left+2;
|
||
by:=Rect.Bottom-3;
|
||
Polygon([Point(ax, ay), Point(ax, by), Point(bx, by)]);
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.CoefKeyPress(Sender: TObject; var Key: Char);
|
||
var
|
||
Allow: boolean;
|
||
i: integer;
|
||
OldVal, NewVal: double;
|
||
begin
|
||
i := 0; OldVal := 0;
|
||
if key = #13 then
|
||
begin
|
||
key := #0;
|
||
Allow := True;
|
||
if Sender = txtA then
|
||
i := 0
|
||
else if Sender = txtB then
|
||
i := 1
|
||
else if Sender = txtC then
|
||
i := 2
|
||
else if Sender = txtD then
|
||
i := 3
|
||
else if Sender = txtE then
|
||
i := 4
|
||
else if Sender = txtF then
|
||
i := 5;
|
||
case i of
|
||
0: OldVal := Round6(cp.xform[SelectedTriangle].c[0][0]); //a
|
||
1: OldVal := Round6(cp.xform[SelectedTriangle].c[1][0]); //b
|
||
2: OldVal := Round6(cp.xform[SelectedTriangle].c[0][1]); //c
|
||
3: OldVal := Round6(cp.xform[SelectedTriangle].c[1][1]); //d
|
||
4: OldVal := Round6(cp.xform[SelectedTriangle].c[2][0]); //e
|
||
5: OldVal := Round6(cp.xform[SelectedTriangle].c[2][1]); //f
|
||
end;
|
||
// OldText := Val;
|
||
{ Test that it's a valid floating point number }
|
||
try
|
||
StrToFloat(TEdit(Sender).Text);
|
||
except on Exception do
|
||
begin
|
||
{ It's not, so we restore the old value }
|
||
TEdit(Sender).Text := Format('%.6g', [OldVal]);
|
||
Allow := False;
|
||
end;
|
||
end;
|
||
NewVal := Round6(StrToFloat(TEdit(Sender).Text));
|
||
TEdit(Sender).Text := Format('%.6g', [NewVal]);
|
||
|
||
{ If it's not the same as the old value and it was valid }
|
||
if (NewVal <> OldVal) and Allow then
|
||
begin
|
||
MainForm.UpdateUndo;
|
||
case i of
|
||
0: cp.xform[SelectedTriangle].c[0][0] := NewVal; //a
|
||
1: cp.xform[SelectedTriangle].c[1][0] := NewVal; //b
|
||
2: cp.xform[SelectedTriangle].c[0][1] := NewVal; //c
|
||
3: cp.xform[SelectedTriangle].c[1][1] := NewVal; //d
|
||
4: cp.xform[SelectedTriangle].c[2][0] := NewVal; //e
|
||
5: cp.xform[SelectedTriangle].c[2][1] := NewVal; //f
|
||
end;
|
||
MainForm.TrianglesFromCP(cp, MainTriangles);
|
||
ShowSelectedInfo;
|
||
UpdateFlame(true);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.CoefExit(Sender: TObject);
|
||
var
|
||
Allow: boolean;
|
||
i: integer;
|
||
NewVal, OldVal: double;
|
||
begin
|
||
i := 0; OldVal := 0;
|
||
Allow := True;
|
||
if Sender = txtA then
|
||
i := 0
|
||
else if Sender = txtB then
|
||
i := 1
|
||
else if Sender = txtC then
|
||
i := 2
|
||
else if Sender = txtD then
|
||
i := 3
|
||
else if Sender = txtE then
|
||
i := 4
|
||
else if Sender = txtF then
|
||
i := 5;
|
||
case i of
|
||
0: OldVal := Round6(cp.xform[SelectedTriangle].c[0][0]); //a
|
||
1: OldVal := Round6(cp.xform[SelectedTriangle].c[1][0]); //b
|
||
2: OldVal := Round6(cp.xform[SelectedTriangle].c[0][1]); //c
|
||
3: OldVal := Round6(cp.xform[SelectedTriangle].c[1][1]); //d
|
||
4: OldVal := Round6(cp.xform[SelectedTriangle].c[2][0]); //e
|
||
5: OldVal := Round6(cp.xform[SelectedTriangle].c[2][1]); //f
|
||
end;
|
||
// OldText := Val;
|
||
{ Test that it's a valid floating point number }
|
||
try
|
||
StrToFloat(TEdit(Sender).Text);
|
||
except on Exception do
|
||
begin
|
||
{ It's not, so we restore the old value }
|
||
TEdit(Sender).Text := Format('%.6g', [OldVal]);
|
||
Allow := False;
|
||
end;
|
||
end;
|
||
NewVal := Round6(StrToFloat(TEdit(Sender).Text));
|
||
TEdit(Sender).Text := Format('%.6g', [NewVal]);
|
||
|
||
{ If it's not the same as the old value and it was valid }
|
||
if (NewVal <> OldVal) and Allow then
|
||
begin
|
||
MainForm.UpdateUndo;
|
||
case i of
|
||
0: cp.xform[SelectedTriangle].c[0][0] := NewVal; //a
|
||
1: cp.xform[SelectedTriangle].c[1][0] := NewVal; //b
|
||
2: cp.xform[SelectedTriangle].c[0][1] := NewVal; //c
|
||
3: cp.xform[SelectedTriangle].c[1][1] := NewVal; //d
|
||
4: cp.xform[SelectedTriangle].c[2][0] := NewVal; //e
|
||
5: cp.xform[SelectedTriangle].c[2][1] := NewVal; //f
|
||
end;
|
||
MainForm.TrianglesFromCP(cp, MainTriangles);
|
||
ShowSelectedInfo;
|
||
UpdateFlame(true);
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.scrlXFormColorScroll(Sender: TObject;
|
||
ScrollCode: TScrollCode; var ScrollPos: Integer);
|
||
begin
|
||
if ScrollCode = scEndScroll then UpdateFlame(True);
|
||
end;
|
||
|
||
procedure TEditForm.scrlXFormColorChange(Sender: TObject);
|
||
begin
|
||
cp.xform[SelectedTriangle].color := (scrlXFormColor.Position) / scrlXFormColor.Max;
|
||
txtXFormColor.Text := Format('%1.3f', [cp.xform[SelectedTriangle].color]);
|
||
pnlXFormColor.color := ColorValToColor(MainCp.cmap, cp.xform[SelectedTriangle].color);
|
||
{
|
||
with ColorImage.Canvas do ///..........!
|
||
begin
|
||
Row := Bitmap.Scanline[0];
|
||
for i := 0 to Bitmap.Width - 1 do
|
||
begin
|
||
with Row[i] do
|
||
begin
|
||
rgbtRed := Palette[i][0];
|
||
rgbtGreen := Palette[i][1];
|
||
rgbtBlue := Palette[i][2];
|
||
end;
|
||
end;
|
||
end;
|
||
}
|
||
DrawPreview;
|
||
end;
|
||
|
||
procedure TEditForm.chkUseXFormColorClick(Sender: TObject);
|
||
begin
|
||
UseTransformColors := chkUseXFormColor.checked;
|
||
DrawGraph;
|
||
end;
|
||
|
||
procedure TEditForm.chkFlameBackClick(Sender: TObject);
|
||
begin
|
||
UseFlameBackground := chkFlameBack.checked;
|
||
DrawGraph;
|
||
end;
|
||
|
||
procedure TEditForm.pnlBackColorClick(Sender: TObject);
|
||
begin
|
||
AdjustForm.ColorDialog.Color := pnlBackColor.Color;
|
||
if AdjustForm.ColorDialog.Execute then
|
||
begin
|
||
pnlBackColor.Color := AdjustForm.ColorDialog.Color;
|
||
BackgroundColor := Integer(pnlBackColor.color);
|
||
GrphPnl.Color := BackgroundColor;
|
||
DrawGraph;
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.pnlReferenceClick(Sender: TObject);
|
||
begin
|
||
AdjustForm.ColorDialog.Color := pnlReference.Color;
|
||
if AdjustForm.ColorDialog.Execute then
|
||
begin
|
||
pnlReference.Color := AdjustForm.ColorDialog.Color;
|
||
ReferenceTriangleColor := Integer(pnlReference.color);
|
||
DrawGraph;
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.pnlGridColor1Click(Sender: TObject);
|
||
begin
|
||
AdjustForm.ColorDialog.Color := pnlGridColor1.Color;
|
||
if AdjustForm.ColorDialog.Execute then
|
||
begin
|
||
pnlGridColor1.Color := AdjustForm.ColorDialog.Color;
|
||
GridColor1 := Integer(pnlGridColor1.color);
|
||
DrawGraph;
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.pnlGridColor2Click(Sender: TObject);
|
||
begin
|
||
AdjustForm.ColorDialog.Color := pnlGridColor2.Color;
|
||
if AdjustForm.ColorDialog.Execute then
|
||
begin
|
||
pnlGridColor2.Color := AdjustForm.ColorDialog.Color;
|
||
GridColor2 := Integer(pnlGridColor2.color);
|
||
DrawGraph;
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.txtXFormColorExit(Sender: TObject);
|
||
var
|
||
v: double;
|
||
begin
|
||
try
|
||
v := StrToFloat(txtXFormColor.Text);
|
||
except on EConvertError do
|
||
begin
|
||
txtXformColor.text := Format('%1.3f', [cp.xform[SelectedTriangle].color]);//FLoatToStr(cp.xform[SelectedTriangle].color);
|
||
exit;
|
||
end;
|
||
end;
|
||
if v > 1 then v := 1;
|
||
if v < 0 then v := 0;
|
||
if v <> cp.xform[SelectedTriangle].color then
|
||
begin
|
||
scrlXFormColor.Position := round(v * scrlXFormColor.Max);
|
||
UpdateFlame(true);
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.txtXFormColorKeyPress(Sender: TObject; var Key: Char);
|
||
var
|
||
v: double;
|
||
begin
|
||
if key = #13 then
|
||
begin
|
||
key := #0;
|
||
try
|
||
v := StrToFloat(txtXFormColor.Text);
|
||
except on EConvertError do
|
||
begin
|
||
txtXformColor.text := Format('%1.3f', [cp.xform[SelectedTriangle].color]);//FLoattoStr(cp.xform[SelectedTriangle].color);
|
||
exit;
|
||
end;
|
||
end;
|
||
if v > 1 then v := 1;
|
||
if v < 0 then v := 0;
|
||
if v <> cp.xform[SelectedTriangle].color then
|
||
begin
|
||
scrlXFormColor.Position := round(v * scrlXFormColor.Max);
|
||
UpdateFlame(true);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.txtSymmetryExit(Sender: TObject);
|
||
var
|
||
Allow: boolean;
|
||
NewVal, OldVal: double;
|
||
begin
|
||
Allow := True;
|
||
OldVal := Round6(cp.xform[SelectedTriangle].symmetry);
|
||
{ Test that it's a valid floating point number }
|
||
try
|
||
StrToFloat(TEdit(Sender).Text);
|
||
except on Exception do
|
||
begin
|
||
{ It's not, so we restore the old value }
|
||
TEdit(Sender).Text := Format('%.6g', [OldVal]);
|
||
Allow := False;
|
||
end;
|
||
end;
|
||
NewVal := Round6(StrToFloat(TEdit(Sender).Text));
|
||
if NewVal < 0 then NewVal := 0;
|
||
if NewVal > 1 then NewVal := 1;
|
||
{ If it's not the same as the old value and it was valid }
|
||
TEdit(Sender).Text := Format('%.6g', [NewVal]);
|
||
if (OldVal <> NewVal) and Allow then
|
||
begin
|
||
MainForm.UpdateUndo;
|
||
cp.xform[SelectedTriangle].symmetry := NewVal;
|
||
UpdateFlame(True);
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.txtSymmetryKeyPress(Sender: TObject; var Key: Char);
|
||
var
|
||
Allow: boolean;
|
||
NewVal, OldVal: double;
|
||
begin
|
||
if key = #13 then
|
||
begin
|
||
{ Stop the beep }
|
||
Key := #0;
|
||
Allow := True;
|
||
OldVal := Round6(cp.xform[SelectedTriangle].symmetry);
|
||
{ Test that it's a valid floating point number }
|
||
try
|
||
StrToFloat(TEdit(Sender).Text);
|
||
except on Exception do
|
||
begin
|
||
{ It's not, so we restore the old value }
|
||
TEdit(Sender).Text := Format('%.6g', [OldVal]);
|
||
Allow := False;
|
||
end;
|
||
end;
|
||
NewVal := Round6(StrToFloat(TEdit(Sender).Text));
|
||
if NewVal < 0 then NewVal := 0;
|
||
if NewVal > 1 then NewVal := 1;
|
||
{ If it's not the same as the old value and it was valid }
|
||
TEdit(Sender).Text := Format('%.6g', [NewVal]);
|
||
if (OldVal <> NewVal) and Allow then
|
||
begin
|
||
MainForm.UpdateUndo;
|
||
cp.xform[SelectedTriangle].symmetry := NewVal;
|
||
UpdateFlame(True);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.VEVarsKeyPress(Sender: TObject; var Key: Char);
|
||
var
|
||
Allow: boolean;
|
||
i: integer;
|
||
NewVal, OldVal: double;
|
||
begin
|
||
if key = #13 then
|
||
begin
|
||
key := #0;
|
||
Allow := True;
|
||
|
||
i := EditForm.VEVars.Row - 1;
|
||
|
||
OldVal := Round6(cp.xform[SelectedTriangle].vars[i]);
|
||
{ Test that it's a valid floating point number }
|
||
try
|
||
StrToFloat(VEVars.Values[VarNames(i)]);
|
||
except on Exception do
|
||
begin
|
||
{ It's not, so we restore the old value }
|
||
VEVars.Values[VarNames(i)] := Format('%.6g', [OldVal]);
|
||
Allow := False;
|
||
end;
|
||
end;
|
||
NewVal := Round6(StrToFloat(VEVars.Values[VarNames(i)]));
|
||
// if NewVal < 0 then NewVal := 0;
|
||
VEVars.Values[VarNames(i)] := Format('%.6g', [NewVal]);
|
||
|
||
{ If it's not the same as the old value and it was valid }
|
||
if (NewVal <> OldVal) and Allow then
|
||
begin
|
||
MainForm.UpdateUndo;
|
||
// EditedVariation := i;
|
||
cp.xform[SelectedTriangle].vars[i] := NewVal;
|
||
// VarNormalize(cp);
|
||
VEVars.Values[VarNames(i)] := Format('%.6g', [cp.xform[SelectedTriangle].vars[i]]);
|
||
ShowSelectedInfo;
|
||
UpdateFlame(True);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.VEVarsExit(Sender: TObject);
|
||
var
|
||
Allow: boolean;
|
||
i: integer;
|
||
NewVal, OldVal: double;
|
||
begin
|
||
Allow := True;
|
||
|
||
i := EditForm.VEVars.Row - 1;
|
||
|
||
OldVal := Round6(cp.xform[SelectedTriangle].vars[i]);
|
||
{ Test that it's a valid floating point number }
|
||
try
|
||
StrToFloat(VEVars.Values[VarNames(i)]);
|
||
except on Exception do
|
||
begin
|
||
{ It's not, so we restore the old value }
|
||
VEVars.Values[VarNames(i)] := Format('%.6g', [OldVal]);
|
||
Allow := False;
|
||
end;
|
||
end;
|
||
NewVal := Round6( StrToFloat(VEVars.Values[VarNames(i)]) );
|
||
VEVars.Values[VarNames(i)] := Format('%.6g', [NewVal]);
|
||
|
||
{ If it's not the same as the old value and it was valid }
|
||
if (NewVal <> OldVal) and Allow then
|
||
begin
|
||
MainForm.UpdateUndo;
|
||
// EditedVariation := i;
|
||
cp.xform[SelectedTriangle].vars[i] := NewVal;
|
||
VEVars.Values[VarNames(i)] := Format('%.6g', [cp.xform[SelectedTriangle].vars[i]]);
|
||
ShowSelectedInfo;
|
||
UpdateFlame(True);
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.VEVarsValidate(Sender: TObject; ACol, ARow: Integer; const KeyName, KeyValue: String);
|
||
var
|
||
Allow: boolean;
|
||
i: integer;
|
||
NewVal, OldVal: double;
|
||
begin
|
||
Allow := True;
|
||
|
||
i := EditForm.VEVars.Row - 1;
|
||
|
||
OldVal := Round6(cp.xform[SelectedTriangle].vars[i]);
|
||
{ Test that it's a valid floating point number }
|
||
try
|
||
StrToFloat(VEVars.Values[VarNames(i)]);
|
||
except on Exception do
|
||
begin
|
||
{ It's not, so we restore the old value }
|
||
VEVars.Values[VarNames(i)] := Format('%.6g', [OldVal]);
|
||
Allow := False;
|
||
end;
|
||
end;
|
||
NewVal := Round6(StrToFloat(VEVars.Values[VarNames(i)]));
|
||
// if NewVal < 0 then NewVal := 0;
|
||
VEVars.Values[VarNames(i)] := Format('%.6g', [NewVal]);
|
||
|
||
{ If it's not the same as the old value and it was valid }
|
||
if (NewVal <> OldVal) and Allow then
|
||
begin
|
||
MainForm.UpdateUndo;
|
||
// EditedVariation := i;
|
||
cp.xform[SelectedTriangle].vars[i] := NewVal;
|
||
// VarNormalize(cp);
|
||
VEVars.Values[VarNames(i)] := Format('%.6g', [cp.xform[SelectedTriangle].vars[i]]);
|
||
ShowSelectedInfo;
|
||
UpdateFlame(True);
|
||
end;
|
||
end;
|
||
|
||
{ **************************************************************************** }
|
||
|
||
function TEditForm.GetPivot: TSPoint;
|
||
begin
|
||
case (rgPivot.ItemIndex) of
|
||
0: begin
|
||
Result.x:=MainTriangles[SelectedTriangle].x[0];
|
||
Result.y:=MainTriangles[SelectedTriangle].y[0];
|
||
end;
|
||
1: begin
|
||
Result.x:=MainTriangles[SelectedTriangle].x[1];
|
||
Result.y:=MainTriangles[SelectedTriangle].y[1];
|
||
end;
|
||
2: begin
|
||
Result.x:=MainTriangles[SelectedTriangle].x[2];
|
||
Result.y:=MainTriangles[SelectedTriangle].y[2];
|
||
end;
|
||
3: Result:=Centroid(MainTriangles[SelectedTriangle]);
|
||
else
|
||
Result.x:=0;
|
||
Result.y:=0;
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.btTrgRotateLeftClick(Sender: TObject);
|
||
var
|
||
offset: double;
|
||
begin
|
||
try
|
||
offset := StrToFloat(txtTrgRotateValue.Text);
|
||
except
|
||
offset := 0;
|
||
txtTrgRotateValue.Text := '0';
|
||
end;
|
||
if offset <> 0 then
|
||
begin
|
||
MainForm.UpdateUndo;
|
||
MainTriangles[SelectedTriangle] :=
|
||
RotateTrianglePoint(MainTriangles[SelectedTriangle], GetPivot.x, GetPivot.y, (PI/180)*offset);
|
||
HasChanged := True;
|
||
UpdateFlame(true);
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.btTrgRotateLeft90Click(Sender: TObject);
|
||
begin
|
||
MainForm.UpdateUndo;
|
||
MainTriangles[SelectedTriangle] :=
|
||
RotateTrianglePoint(MainTriangles[SelectedTriangle], GetPivot.x, GetPivot.y, PI/2);
|
||
HasChanged := True;
|
||
UpdateFlame(true);
|
||
end;
|
||
|
||
procedure TEditForm.btTrgRotateRightClick(Sender: TObject);
|
||
var
|
||
offset: double;
|
||
begin
|
||
try
|
||
offset := StrToFloat(txtTrgRotateValue.Text);
|
||
except
|
||
offset := 0;
|
||
txtTrgRotateValue.Text := '0';
|
||
end;
|
||
if offset <> 0 then
|
||
begin
|
||
MainForm.UpdateUndo;
|
||
MainTriangles[SelectedTriangle] :=
|
||
RotateTrianglePoint(MainTriangles[SelectedTriangle], GetPivot.x, GetPivot.y, -((PI/180) * offset));
|
||
HasChanged := True;
|
||
UpdateFlame(true);
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.btTrgRotateRight90Click(Sender: TObject);
|
||
begin
|
||
MainForm.UpdateUndo;
|
||
MainTriangles[SelectedTriangle] :=
|
||
RotateTrianglePoint(MainTriangles[SelectedTriangle], GetPivot.x, GetPivot.y, -PI/2);
|
||
HasChanged := True;
|
||
UpdateFlame(true);
|
||
end;
|
||
|
||
procedure TEditForm.TrgMove(dx, dy: double);
|
||
var
|
||
i: integer;
|
||
offset: double;
|
||
begin
|
||
try
|
||
offset := StrToFloat(txtTrgMoveValue.Text);
|
||
except
|
||
offset := 0;
|
||
txtTrgMoveValue.Text := '0';
|
||
end;
|
||
if offset <> 0 then
|
||
begin
|
||
MainForm.UpdateUndo;
|
||
for i := 0 to 2 do begin
|
||
MainTriangles[SelectedTriangle].x[i] :=
|
||
MainTriangles[SelectedTriangle].x[i] + dx*offset;
|
||
MainTriangles[SelectedTriangle].y[i] :=
|
||
MainTriangles[SelectedTriangle].y[i] + dy*offset;
|
||
end;
|
||
HasChanged := True;
|
||
UpdateFlame(true);
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.btTrgMoveLeftClick(Sender: TObject);
|
||
begin
|
||
TrgMove(-1,0);
|
||
end;
|
||
|
||
procedure TEditForm.btTrgMoveRightClick(Sender: TObject);
|
||
begin
|
||
TrgMove(1,0);
|
||
end;
|
||
|
||
procedure TEditForm.btTrgMoveUpClick(Sender: TObject);
|
||
begin
|
||
TrgMove(0,1);
|
||
end;
|
||
|
||
procedure TEditForm.btTrgMoveDownClick(Sender: TObject);
|
||
begin
|
||
TrgMove(0,-1);
|
||
end;
|
||
|
||
procedure TEditForm.btTrgMoveLUClick(Sender: TObject);
|
||
begin
|
||
TrgMove(-1,1);
|
||
end;
|
||
|
||
procedure TEditForm.btTrgMoveLDClick(Sender: TObject);
|
||
begin
|
||
TrgMove(-1,-1);
|
||
end;
|
||
|
||
procedure TEditForm.btTrgMoveRUClick(Sender: TObject);
|
||
begin
|
||
TrgMove(1,1);
|
||
end;
|
||
|
||
procedure TEditForm.btTrgMoveRDClick(Sender: TObject);
|
||
begin
|
||
TrgMove(1,-1);
|
||
end;
|
||
|
||
procedure TEditForm.btTrgScaleUpClick(Sender: TObject);
|
||
var
|
||
scale: double;
|
||
begin
|
||
try
|
||
scale := StrToFloat(txtTrgScaleValue.Text);
|
||
except
|
||
scale := 0.0;
|
||
txtTrgScaleValue.Text := '0.0';
|
||
end;
|
||
if scale <> 0 then
|
||
begin
|
||
MainForm.UpdateUndo;
|
||
MainTriangles[SelectedTriangle] :=
|
||
ScaleTrianglePoint(MainTriangles[SelectedTriangle], GetPivot.x, GetPivot.y, 1.0+scale);
|
||
HasChanged := True;
|
||
UpdateFlame(true);
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.btTrgScaleDownClick(Sender: TObject);
|
||
var
|
||
scale: double;
|
||
begin
|
||
try
|
||
scale := StrToFloat(txtTrgScaleValue.Text);
|
||
except
|
||
scale := 0.0;
|
||
txtTrgScaleValue.Text := '0.0';
|
||
end;
|
||
if scale <> 0 then
|
||
begin
|
||
MainForm.UpdateUndo;
|
||
MainTriangles[SelectedTriangle] :=
|
||
ScaleTrianglePoint(MainTriangles[SelectedTriangle], GetPivot.x, GetPivot.y, 1.0-scale);
|
||
HasChanged := True;
|
||
UpdateFlame(true);
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.editKeyDown(Sender: TObject; var Key: Word;
|
||
Shift: TShiftState);
|
||
var
|
||
coeff: double;
|
||
label goNext;
|
||
begin
|
||
if Shift = [ssShift] then coeff := 10
|
||
else if Shift = [ssCtrl] then coeff := 0.1
|
||
else coeff := 1.0;
|
||
|
||
// if (PageControl.TabIndex <> 2) or // variations
|
||
// (PageControl.TabIndex <> 3) then // variables
|
||
begin
|
||
// MainForm.UpdateUndo;
|
||
case key of
|
||
VK_LEFT:
|
||
if Shift = [ssAlt] then btTrgRotateLeftClick(Sender)
|
||
else TrgMove(-coeff,0);
|
||
VK_RIGHT:
|
||
if Shift = [ssAlt] then btTrgRotateRightClick(Sender)
|
||
else TrgMove(coeff,0);
|
||
VK_UP:
|
||
if Shift = [ssAlt] then btTrgScaleUpClick(Sender)
|
||
else TrgMove(0,coeff);
|
||
VK_DOWN:
|
||
if Shift = [ssAlt] then btTrgScaleDownClick(Sender)
|
||
else TrgMove(0,-coeff);
|
||
VK_PRIOR: btTrgRotateLeftClick(Sender);
|
||
VK_NEXT: btTrgRotateRightClick(Sender);
|
||
VK_HOME: btTrgScaleUpClick(Sender);
|
||
VK_END: btTrgScaleDownClick(Sender);
|
||
VK_INSERT: mnuDupClick(Sender);
|
||
VK_DELETE: {if Shift = [ssShift] then} mnuDeleteClick(Sender);
|
||
else goto goNext;
|
||
end;
|
||
// HasChanged := True;
|
||
key_handled:=true;
|
||
exit;
|
||
end;
|
||
|
||
goNext:
|
||
|
||
case key of
|
||
VK_ADD:
|
||
if SelectedTriangle < Transforms-1 then begin
|
||
Inc(SelectedTriangle);
|
||
DrawGraph;
|
||
ShowSelectedInfo;
|
||
end;
|
||
VK_SUBTRACT:
|
||
if SelectedTriangle > 0 then begin
|
||
Dec(SelectedTriangle);
|
||
DrawGraph;
|
||
ShowSelectedInfo;
|
||
end;
|
||
VK_SPACE: EditForm.tbSelectClick(Sender);
|
||
|
||
Ord('Q'): EditForm.tbEditModeClick(tbMove);
|
||
Ord('W'): EditForm.tbEditModeClick(tbRotate);
|
||
Ord('E'): EditForm.tbEditModeClick(tbScale);
|
||
|
||
Ord('A'): PageControl.TabIndex := 0;
|
||
Ord('S'): PageControl.TabIndex := 1;
|
||
Ord('D'): PageControl.TabIndex := 2;
|
||
Ord('F'): PageControl.TabIndex := 3;
|
||
|
||
Ord('Z'): EditForm.rgPivot.ItemIndex:=0;
|
||
Ord('X'): EditForm.rgPivot.ItemIndex:=1;
|
||
Ord('C'): EditForm.rgPivot.ItemIndex:=2;
|
||
Ord('V'): EditForm.rgPivot.ItemIndex:=3;
|
||
Ord('B'): EditForm.rgPivot.ItemIndex:=4;
|
||
else
|
||
key_handled := false;
|
||
exit;
|
||
end;
|
||
key := 0;
|
||
key_handled := true;
|
||
end;
|
||
|
||
procedure TEditForm.editKeyPress(Sender: TObject; var Key: Char);
|
||
begin
|
||
// if key_handled then key := #0 else
|
||
if key in ['A'..'z'] then key := #0; // hmmm...
|
||
end;
|
||
|
||
procedure TEditForm.splitterMoved(Sender: TObject);
|
||
begin
|
||
UpdateDisplay;
|
||
end;
|
||
|
||
procedure TEditForm.tbSelectClick(Sender: TObject);
|
||
begin
|
||
SelectMode := not SelectMode;
|
||
tbSelect.Down := SelectMode;
|
||
|
||
if SelectMode then
|
||
begin
|
||
StatusBar.Panels[2].Text := 'Select ON'
|
||
end
|
||
else begin
|
||
mouseOverTriangle := SelectedTriangle;
|
||
StatusBar.Panels[2].Text := 'Select OFF';
|
||
end;
|
||
|
||
// hack (to generate MouseMove event):
|
||
GetCursorPos(MousePos);
|
||
SetCursorPos(MousePos.x, MousePos.y);
|
||
end;
|
||
|
||
procedure TEditForm.editMouseWheel(Sender: TObject; Shift: TShiftState;
|
||
WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
|
||
begin
|
||
if WheelDelta > 0 then GraphZoom := GraphZoom * 1.25
|
||
else GraphZoom := GraphZoom * 0.8;
|
||
EditForm.StatusBar.Panels[2].Text := Format('Zoom: %f', [GraphZoom]);
|
||
|
||
DrawGraph;
|
||
Handled := true;
|
||
end;
|
||
|
||
procedure TEditForm.PreviewImageDblClick(Sender: TObject);
|
||
begin
|
||
MainForm.UpdateUndo;
|
||
MainForm.ResetLocation;
|
||
MainForm.RedrawTimer.enabled := true;
|
||
MainForm.UpdateWindows;
|
||
end;
|
||
|
||
procedure TEditForm.rgPivotClicked(Sender: TObject);
|
||
begin
|
||
DrawGraph;
|
||
end;
|
||
|
||
{
|
||
procedure TEditForm.VEVarsSelectCell(Sender: TObject; ACol, ARow: Integer;
|
||
var CanSelect: Boolean);
|
||
begin
|
||
DrawGraph;
|
||
end;
|
||
}
|
||
|
||
procedure TEditForm.tbEditModeClick(Sender: TObject);
|
||
begin
|
||
if Sender = tbRotate then editMode := modeRotate
|
||
else if Sender = tbScale then editMode := modeScale
|
||
else editMode := modeMove;
|
||
tbMove.Down := (editMode = modeMove);
|
||
tbRotate.Down := (editMode = modeRotate);
|
||
tbScale.Down := (editMode = modeScale);
|
||
end;
|
||
|
||
// --Z-- Variation List Editor
|
||
|
||
procedure TEditForm.VEVarsMouseDown(Sender: TObject; Button: TMouseButton;
|
||
Shift: TShiftState; X, Y: Integer);
|
||
var
|
||
cell: TGridCoord;
|
||
begin
|
||
if Button = mbLeft then begin
|
||
cell:=VEVars.MouseCoord(x, y);
|
||
VEVars.Row := cell.Y;
|
||
varDragIndex := cell.Y-1;
|
||
Screen.Cursor := crHSplit;
|
||
|
||
GetCursorPos(mousepos); // hmmm
|
||
|
||
varDragMode:=true;
|
||
varDragPos:=x;
|
||
SetCaptureControl(VEVars);
|
||
|
||
HasChanged := False;
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.VEVarsMouseMove(Sender: TObject; Shift: TShiftState; X,
|
||
Y: Integer);
|
||
var
|
||
v: double;
|
||
cell: TGridCoord;
|
||
begin
|
||
cell := VEVars.MouseCoord(x, y);
|
||
if (cell.Y > 0) and (cell.X = 0) then VEVars.Cursor := crHandPoint
|
||
else VEVars.Cursor := crDefault;
|
||
|
||
if varMM then // hack
|
||
begin
|
||
varMM:=false;
|
||
varDragPos:=x;
|
||
end
|
||
else
|
||
if varDragMode and (x <> varDragPos) then
|
||
begin
|
||
v := cp.xform[SelectedTriangle].vars[varDragIndex];
|
||
v := RoundTo(v + ((x-varDragPos)*2)/1000.0, -3);
|
||
|
||
varDragPos:=x;
|
||
SetCursorPos(MousePos.x, MousePos.y); // hmmm
|
||
varMM:=true;
|
||
|
||
cp.xform[SelectedTriangle].vars[varDragIndex] := v;
|
||
VEVars.Values[VarNames(varDragIndex)] := Format('%.6g', [v]);
|
||
|
||
HasChanged := True;
|
||
UpdateFlameX;
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.VEVarsMouseUp(Sender: TObject; Button: TMouseButton;
|
||
Shift: TShiftState; X, Y: Integer);
|
||
begin
|
||
if Button <> mbLeft then exit;
|
||
SetCaptureControl(nil);
|
||
if varDragMode then
|
||
begin
|
||
varDragMode:=false;
|
||
Screen.Cursor := crDefault;
|
||
|
||
if HasChanged then
|
||
begin
|
||
MainForm.UpdateUndo;
|
||
UpdateFlame(true);
|
||
HasChanged := False;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.VEVarsDblClick(Sender: TObject);
|
||
begin
|
||
if cp.xform[SelectedTriangle].vars[varDragIndex] = 0 then exit;
|
||
|
||
MainForm.UpdateUndo;
|
||
cp.xform[SelectedTriangle].vars[varDragIndex] := 0;
|
||
VEVars.Values[VarNames(varDragIndex)] := '0';
|
||
HasChanged := True;
|
||
UpdateFlameX;
|
||
end;
|
||
|
||
procedure TEditForm.VEVarsDrawCell(Sender: TObject; ACol, ARow: Integer;
|
||
Rect: TRect; State: TGridDrawState);
|
||
begin
|
||
{
|
||
if ARow = VEVars.Row then
|
||
with VEVars.Canvas do
|
||
begin
|
||
Brush.Color := clHighlight;
|
||
FillRect(Rect);
|
||
// VEVars.Refresh;
|
||
end;
|
||
//inherited;
|
||
}
|
||
end;
|
||
|
||
procedure TEditForm.cbKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
|
||
begin
|
||
key:=0;
|
||
end;
|
||
|
||
procedure TEditForm.tbFullViewClick(Sender: TObject);
|
||
begin
|
||
MainForm.mnuFullScreenClick(Sender);
|
||
end;
|
||
|
||
// --Z-- // transform color scroller - TODO
|
||
|
||
procedure TEditForm.ColorImageMouseDown(Sender: TObject;
|
||
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
||
begin
|
||
if Button = mbLeft then
|
||
begin
|
||
colorDragX:=x;
|
||
colorOldX:=x;
|
||
// BackupPal:=Palette;
|
||
colorDrag:=true;
|
||
colorChanged:=false;
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.ColorImageMouseMove(Sender: TObject;
|
||
Shift: TShiftState; X, Y: Integer);
|
||
var
|
||
i, offset: integer;
|
||
begin
|
||
{
|
||
if colorDrag and (oldX<>x) then
|
||
begin
|
||
oldX:=x;
|
||
offset := ( ((x - colorDragX) shl 8) div ColorImage.Width ) mod 256;
|
||
colorChanged := true;
|
||
|
||
for i := 0 to 255 do
|
||
begin
|
||
Palette[i][0] := BackupPal[(255 + i - offset) and $FF][0];
|
||
Palette[i][1] := BackupPal[(255 + i - offset) and $FF][1];
|
||
Palette[i][2] := BackupPal[(255 + i - offset) and $FF][2];
|
||
end;
|
||
|
||
cp.CmapIndex := cmbPalette.ItemIndex;
|
||
cp.cmap := Palette;
|
||
|
||
colorImage.Refresh;
|
||
end;
|
||
}
|
||
end;
|
||
|
||
procedure TEditForm.ColorImageMouseUp(Sender: TObject;
|
||
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
||
begin
|
||
if colorDrag then
|
||
begin
|
||
colorDrag := false;
|
||
|
||
if colorChanged then begin
|
||
// MainForm.UpdateUndo;
|
||
// cp.xxx := xxx;
|
||
// MainCP.copy(cp);
|
||
// UpdateXXXX;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.vleVariablesExit(Sender: TObject);
|
||
var
|
||
Allow: boolean;
|
||
i: integer;
|
||
NewVal, OldVal: double;
|
||
begin
|
||
Allow := True;
|
||
|
||
i := vleVariables.Row;
|
||
|
||
cp.xform[SelectedTriangle].GetVariable(vleVariables.Keys[i], OldVal);
|
||
{ Test that it's a valid floating point number }
|
||
try
|
||
StrToFloat(vleVariables.Values[vleVariables.Keys[i]]);
|
||
except on Exception do
|
||
begin
|
||
{ It's not, so we restore the old value }
|
||
vleVariables.Values[vleVariables.Keys[i]] := Format('%.6g', [OldVal]);
|
||
Allow := False;
|
||
end;
|
||
end;
|
||
|
||
NewVal := Round6(StrToFloat(vleVariables.Values[vleVariables.Keys[i]]));
|
||
vleVariables.Values[vleVariables.Keys[i]] := Format('%.6g', [NewVal]);
|
||
|
||
{ If it's not the same as the old value and it was valid }
|
||
if (NewVal <> OldVal) and Allow then
|
||
begin
|
||
MainForm.UpdateUndo;
|
||
cp.xform[SelectedTriangle].SetVariable(vleVariables.Keys[i], NewVal);
|
||
vleVariables.Values[vleVariables.Keys[i]] := Format('%.6g', [NewVal]);
|
||
ShowSelectedInfo;
|
||
UpdateFlame(True);
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.vleVariablesKeyPress(Sender: TObject; var Key: Char);
|
||
var
|
||
Allow: boolean;
|
||
i: integer;
|
||
NewVal, OldVal: double;
|
||
begin
|
||
if key <> #13 then
|
||
Exit;
|
||
|
||
key := #0;
|
||
|
||
Allow := True;
|
||
|
||
i := vleVariables.Row;
|
||
|
||
cp.xform[SelectedTriangle].GetVariable(vleVariables.Keys[i], OldVal);
|
||
{ Test that it's a valid floating point number }
|
||
try
|
||
StrToFloat(vleVariables.Values[vleVariables.Keys[i]]);
|
||
except on Exception do
|
||
begin
|
||
{ It's not, so we restore the old value }
|
||
vleVariables.Values[vleVariables.Keys[i]] := Format('%.6g', [OldVal]);
|
||
Allow := False;
|
||
end;
|
||
end;
|
||
|
||
NewVal := Round6(StrToFloat(vleVariables.Values[vleVariables.Keys[i]]));
|
||
vleVariables.Values[vleVariables.Keys[i]] := Format('%.6g', [NewVal]);
|
||
|
||
{ If it's not the same as the old value and it was valid }
|
||
if (NewVal <> OldVal) and Allow then
|
||
begin
|
||
MainForm.UpdateUndo;
|
||
cp.xform[SelectedTriangle].SetVariable(vleVariables.Keys[i], NewVal);
|
||
vleVariables.Values[vleVariables.Keys[i]] := Format('%.6g', [NewVal]);
|
||
ShowSelectedInfo;
|
||
UpdateFlame(True);
|
||
end;
|
||
end;
|
||
|
||
procedure TEditForm.vleVariablesValidate(Sender: TObject; ACol, ARow: Integer; const KeyName, KeyValue: string);
|
||
var
|
||
Allow: boolean;
|
||
i: integer;
|
||
NewVal, OldVal: double;
|
||
begin
|
||
Allow := True;
|
||
|
||
i := vleVariables.Row;
|
||
|
||
cp.xform[SelectedTriangle].GetVariable(vleVariables.Keys[i], OldVal);
|
||
{ Test that it's a valid floating point number }
|
||
try
|
||
StrToFloat(vleVariables.Values[vleVariables.Keys[i]]);
|
||
except on Exception do
|
||
begin
|
||
{ It's not, so we restore the old value }
|
||
vleVariables.Values[vleVariables.Keys[i]] := Format('%.6g', [OldVal]);
|
||
Allow := False;
|
||
end;
|
||
end;
|
||
|
||
NewVal := Round6(StrToFloat(vleVariables.Values[vleVariables.Keys[i]]));
|
||
vleVariables.Values[vleVariables.Keys[i]] := Format('%.6g', [NewVal]);
|
||
|
||
{ If it's not the same as the old value and it was valid }
|
||
if (NewVal <> OldVal) and Allow then
|
||
begin
|
||
MainForm.UpdateUndo;
|
||
cp.xform[SelectedTriangle].SetVariable(vleVariables.Keys[i], NewVal);
|
||
vleVariables.Values[vleVariables.Keys[i]] := Format('%.6g', [NewVal]);
|
||
ShowSelectedInfo;
|
||
UpdateFlame(True);
|
||
end;
|
||
end;
|
||
|
||
end.
|
||
|