{ Apophysis Copyright (C) 2001-2004 Mark Townsend Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina 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. } unit Adjust; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls, Buttons, Menus, CurvesControl, ControlPoint, Cmap, RenderingInterface, Translation; const WM_UPDATE_PARAMS = WM_APP + 5439; type TAdjustForm = class(TForm) QualityPopup: TPopupMenu; mnuLowQuality: TMenuItem; mnuMediumQuality: TMenuItem; mnuHighQuality: TMenuItem; ColorDialog: TColorDialog; PrevPnl: TPanel; PreviewImage: TImage; PageControl: TPageControl; TabCamera: TTabSheet; scrollZoom: TScrollBar; txtZoom: TEdit; scrollCenterX: TScrollBar; txtCenterX: TEdit; scrollCenterY: TScrollBar; txtCenterY: TEdit; TabRendering: TTabSheet; scrollGamma: TScrollBar; txtGamma: TEdit; scrollBrightness: TScrollBar; txtBrightness: TEdit; scrollVibrancy: TScrollBar; txtVibrancy: TEdit; ColorPanel: TPanel; TabGradient: TTabSheet; scrollAngle: TScrollBar; txtAngle: TEdit; GradientPnl: TPanel; GradientImage: TImage; ScrollBar: TScrollBar; btnOpen: TSpeedButton; btnSmoothPalette: TSpeedButton; btnPaste: TSpeedButton; btnCopy: TSpeedButton; cmbPalette: TComboBox; GradientPopup: TPopupMenu; mnuRandomize: TMenuItem; N7: TMenuItem; mnuInvert: TMenuItem; mnuReverse: TMenuItem; N3: TMenuItem; mnuSmoothPalette: TMenuItem; mnuGradientBrowser: TMenuItem; N4: TMenuItem; SaveGradient1: TMenuItem; SaveasMapfile1: TMenuItem; N6: TMenuItem; mnuSaveasDefault: TMenuItem; N5: TMenuItem; mnuCopy: TMenuItem; mnuPaste: TMenuItem; scrollModePopup: TPopupMenu; mnuRotate: TMenuItem; N1: TMenuItem; mnuHue: TMenuItem; mnuSaturation: TMenuItem; mnuBrightness: TMenuItem; Contrast1: TMenuItem; N2: TMenuItem; mnuBlur: TMenuItem; mnuFrequency: TMenuItem; SaveDialog: TSaveDialog; TabSize: TTabSheet; btnPreset1: TButton; btnPreset2: TButton; btnPreset3: TButton; btnColorPreset: TSpeedButton; btnApplySize: TBitBtn; txtWidth: TComboBox; txtHeight: TComboBox; N8: TMenuItem; mnuInstantPreview: TMenuItem; pnlZoom: TPanel; pnlXpos: TPanel; pnlYpos: TPanel; pnlAngle: TPanel; pnlGamma: TPanel; pnlBrightness: TPanel; pnlVibrancy: TPanel; chkResizeMain: TCheckBox; pnlPitch: TPanel; pnlYaw: TPanel; pnlPersp: TPanel; txtPitch: TEdit; txtYaw: TEdit; txtPersp: TEdit; pnlMasterScale: TPanel; editPPU: TEdit; pnlZpos: TPanel; txtZpos: TEdit; pnlGammaThreshold: TPanel; txtGammaThreshold: TEdit; btnUndo: TSpeedButton; btnRedo: TSpeedButton; pnlDOF: TPanel; txtDOF: TEdit; btnSet1: TSpeedButton; btnSet2: TSpeedButton; btnSet3: TSpeedButton; Shape1: TShape; txtVal: TEdit; btnReset: TButton; pnlWidth: TPanel; pnlHeight: TPanel; pnlBackground: TPanel; TabCurves: TTabSheet; CurvesPanel: TPanel; tbWeightLeft: TScrollBar; tbWeightRight: TScrollBar; Panel5: TPanel; cbChannel: TComboBox; btnResetCurves: TButton; N9: TMenuItem; Red1: TMenuItem; Green1: TMenuItem; Blue1: TMenuItem; mnuGreyscale: TMenuItem; mnuRGB2BGR: TMenuItem; Smoothize1: TMenuItem; BGR1: TMenuItem; BRG1: TMenuItem; RBG1: TMenuItem; GRB1: TMenuItem; GBR1: TMenuItem; Removedarkareas1: TMenuItem; N10: TMenuItem; SymmetricGradient1: TMenuItem; Fliplefthalf1: TMenuItem; Fliprighthalf1: TMenuItem; GradStatusBar: TStatusBar; btnSelected: TSpeedButton; SelectedPopup: TPopupMenu; LerpRGB: TMenuItem; LerpHSV: TMenuItem; RandomizeSelected: TMenuItem; Copyfragment1: TMenuItem; Pastefragment1: TMenuItem; N11: TMenuItem; Mixcolors: TMenuItem; N12: TMenuItem; InvertColors: TMenuItem; ReverseFragment: TMenuItem; mnuSetColor: TMenuItem; pnlRoll: TPanel; txtRoll: TEdit; AdjustSelected: TMenuItem; N13: TMenuItem; mnuLuminance: TMenuItem; cbAspectRatio: TComboBox; AdjustColorFragment: TMenuItem; N14: TMenuItem; mnuSepia: TMenuItem; N15: TMenuItem; gbSize: TGroupBox; gbPresets: TGroupBox; gbChange: TGroupBox; GradSelection: TPaintBox; chkTransparent: TCheckBox; pnlContrast: TPanel; scrollContrast: TScrollBar; txtContrast: TEdit; CurvesStatusBar: TStatusBar; SmoothizeSelected: TMenuItem; btResetZoom: TButton; btnMenu: TButton; // AV: changed from TSpeedButton for auto-drawing the arrow SaveAsScript: TMenuItem; lblRatio: TPanel; chkDisplay3DAxes: TCheckBox; // AV procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure FormDestroy(Sender: TObject); procedure DrawPreview; procedure FormShow(Sender: TObject); procedure mnuLowQualityClick(Sender: TObject); procedure mnuMediumQualityClick(Sender: TObject); procedure mnuHighQualityClick(Sender: TObject); procedure txtZoomKeyPress(Sender: TObject; var Key: Char); procedure txtZoomExit(Sender: TObject); procedure txtCenterXKeyPress(Sender: TObject; var Key: Char); procedure txtCenterXExit(Sender: TObject); procedure txtCenterYKeyPress(Sender: TObject; var Key: Char); procedure txtCenterYExit(Sender: TObject); procedure txtGammaKeyPress(Sender: TObject; var Key: Char); procedure txtGammaExit(Sender: TObject); procedure txtBrightnessKeyPress(Sender: TObject; var Key: Char); procedure txtBrightnessExit(Sender: TObject); procedure txtVibrancyKeyPress(Sender: TObject; var Key: Char); procedure txtVibrancyExit(Sender: TObject); procedure scrollCameraScroll(Sender: TObject; ScrollCode: TScrollCode; var ScrollPos: Integer); procedure scrollVibrancyScroll(Sender: TObject); procedure scrollGammaChange(Sender: TObject); procedure scrollBrightnessChange(Sender: TObject); procedure scrollZoomChange(Sender: TObject); procedure scrollCenterXChange(Sender: TObject); procedure scrollCenterYChange(Sender: TObject); procedure ColorPanelClick(Sender: TObject); procedure txtGammaEnter(Sender: TObject); procedure txtBrightnessEnter(Sender: TObject); procedure txtVibrancyEnter(Sender: TObject); procedure txtZoomEnter(Sender: TObject); procedure txtCenterXEnter(Sender: TObject); procedure txtCenterYEnter(Sender: TObject); procedure scrollAngleChange(Sender: TObject); procedure txtAngleEnter(Sender: TObject); procedure txtAngleExit(Sender: TObject); procedure txtAngleKeyPress(Sender: TObject; var Key: Char); // --Z-- // gradient functions procedure cmbPaletteChange(Sender: TObject); // procedure DrawPalette; procedure btnMenuClick(Sender: TObject); procedure mnuReverseClick(Sender: TObject); procedure mnuInvertClick(Sender: TObject); procedure mnuRotateClick(Sender: TObject); procedure mnuHueClick(Sender: TObject); procedure mnuSaturationClick(Sender: TObject); procedure ScrollBarChange(Sender: TObject); procedure mnuBrightnessClick(Sender: TObject); procedure mnuBlurClick(Sender: TObject); procedure btnOpenClick(Sender: TObject); procedure mnuSmoothPaletteClick(Sender: TObject); procedure SaveGradient1Click(Sender: TObject); procedure SaveasMapfile1Click(Sender: TObject); procedure cmbPaletteDrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState); procedure ScrollBarScroll(Sender: TObject; ScrollCode: TScrollCode; var ScrollPos: Integer); procedure btnCopyClick(Sender: TObject); procedure btnPasteClick(Sender: TObject); // procedure ApplicationEventsActivate(Sender: TObject); procedure mnuSaveasDefaultClick(Sender: TObject); procedure mnuRandomizeClick(Sender: TObject); procedure mnuFrequencyClick(Sender: TObject); procedure mnuContrastClick(Sender: TObject); procedure GradImageMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure GradImageMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure GradImageMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure btnSet1Click(Sender: TObject); procedure btnSet2Click(Sender: TObject); procedure btnSet3Click(Sender: TObject); procedure btnPreset1Click(Sender: TObject); procedure btnPreset2Click(Sender: TObject); procedure btnPreset3Click(Sender: TObject); procedure txtWidthChange(Sender: TObject); procedure txtHeightChange(Sender: TObject); procedure txtSizeKeyPress(Sender: TObject; var Key: Char); // procedure chkMaintainClick(Sender: TObject); procedure SetMainWindowSize; procedure GetMainWindowSize; procedure btnUndoClick(Sender: TObject); procedure btnRedoClick(Sender: TObject); procedure GradientImageDblClick(Sender: TObject); procedure btnColorPresetClick(Sender: TObject); procedure btnApplySizeClick(Sender: TObject); procedure mnuInstantPreviewClick(Sender: TObject); procedure editPPUKeyPress(Sender: TObject; var Key: Char); procedure editPPUValidate(Sender: TObject); procedure DragPanelMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure DragPanelMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure DragPanelMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure DragPanelDblClick(Sender: TObject); procedure FormActivate(Sender: TObject); procedure txtCamEnter(Sender: TObject); procedure txtCamPitchExit(Sender: TObject); procedure txtCamPitchKeyPress(Sender: TObject; var Key: Char); procedure txtCamYawExit(Sender: TObject); procedure txtCamYawKeyPress(Sender: TObject; var Key: Char); procedure txtCamDistExit(Sender: TObject); procedure txtCamDistKeyPress(Sender: TObject; var Key: Char); procedure txtCamZposExit(Sender: TObject); procedure txtCamZposKeyPress(Sender: TObject; var Key: Char); procedure txtCamDofExit(Sender: TObject); procedure txtCamDofKeyPress(Sender: TObject; var Key: Char); procedure PreviewImageMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure PreviewImageMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure PreviewImageMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure PreviewImageDblClick(Sender: TObject); procedure txtGammaThresholdKeyPress(Sender: TObject; var Key: Char); procedure txtGammaThresholdEnter(Sender: TObject); procedure txtGammaThresholdExit(Sender: TObject); procedure Shape1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure btnResetClick(Sender: TObject); procedure txtValKeyPress(Sender: TObject; var Key: Char); procedure txtValExit(Sender: TObject); procedure WeightScroll(Sender: TObject; ScrollCode: TScrollCode; var ScrollPos: Integer); procedure WeightChange(Sender: TObject); procedure curveChange(Sender: TObject); procedure btnResetCurvesClick(Sender: TObject); procedure mnuRedClick(Sender: TObject); procedure mnuGreenClick(Sender: TObject); procedure mnuBlueClick(Sender: TObject); procedure mnuGreyscaleClick(Sender: TObject); procedure mnuRGB2BGRClick(Sender: TObject); procedure Smoothize1Click(Sender: TObject); procedure DarkRemoverClick(Sender: TObject); procedure Fliplefthalf1Click(Sender: TObject); procedure Fliprighthalf1Click(Sender: TObject); procedure GradStatusBarDrawPanel(StatusBar: TStatusBar; Panel: TStatusPanel; const Rect: TRect); procedure GradientImageMouseLeave(Sender: TObject); procedure LerpRGBClick(Sender: TObject); procedure LerpHSVClick(Sender: TObject); procedure RandomizeSelectedClick(Sender: TObject); procedure Copyfragment1Click(Sender: TObject); procedure Pastefragment1Click(Sender: TObject); procedure MixcolorsClick(Sender: TObject); procedure InvertColorsClick(Sender: TObject); procedure ReverseFragmentClick(Sender: TObject); procedure mnuSetColorClick(Sender: TObject); procedure txtCamRollExit(Sender: TObject); procedure txtCamRollKeyPress(Sender: TObject; var Key: Char); procedure GradStatusBarDblClick(Sender: TObject); procedure mnuLuminanceClick(Sender: TObject); procedure mnuSepiaClick(Sender: TObject); procedure cbAspectRatioChange(Sender: TObject); procedure ExtSysMenu(var Msg: TMessage); message WM_SysCommand; procedure AdjustColorFragmentClick(Sender: TObject); procedure btnSelectedClick(Sender: TObject); procedure btnSelectedMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure GradSelectionPaint(Sender: TObject); procedure scrollContrastChange(Sender: TObject); procedure txtContrastEnter(Sender: TObject); procedure txtContrastExit(Sender: TObject); procedure txtContrastKeyPress(Sender: TObject; var Key: Char); procedure SmoothizeSelectedClick(Sender: TObject); procedure btResetZoomClick(Sender: TObject); procedure SaveAsScriptClick(Sender: TObject); procedure chkDisplay3DAxesClick(Sender: TObject); private CurvesControl: TCurvesControl; Resetting: boolean; Render: TRenderer; bm: TBitmap; EditBoxValue: string; cp: TControlPoint; pnlDragMode, pnlDragged, pnlMM: boolean; pnlDragPos, pnlDragOld: integer; pnlDragValue: double; mousepos: TPoint; camDragMode, camDragged, camMM: boolean; camDragPos, camDragOld: TPoint; camDragValueX, camDragValueY: double; private // gradient stuff {Palette,} BackupPal: TColorMap; tmpBackupPal: TColorMap; tmpColors: array of array of byte; //integer; // AV scrollMode: (modeRotate, modeHue, modeSaturation, modeLuminance, modeBrightness, modeContrast, modeBlur, modeFrequency, modeRed, modeGreen, modeBlue); GradientChanged: boolean; imgDragMode: (imgDragNone, imgDragRotate, imgDragStretch, imgDragSelect); startX: integer; // AV dragX, oldX: integer; oldpos, offset: integer; // for display...? :-\ const space = ': '; procedure Apply; procedure SetCurvesCp(ccp: TControlPoint); function Blur(const radius: integer; const pal: TColorMap; start, last: byte): TColorMap; function Frequency(const times: Integer; const pal: TColorMap): TColorMap; function FrequencySel(const times: Integer; const pal: TColorMap): TColorMap; procedure SaveMap(FileName: string); procedure UpdateGradient(Pal: TColorMap); private // image size stuff ImageHeight, ImageWidth: integer; Preset: array[1..3] of record Left, Top, Width, Height: integer; end; ratio: double; procedure ReadPreset(n: integer); procedure WritePreset(n: integer); function PresetToStr(n: integer): string; public PreviewDensity: double; Palette: TColorMap; // AV: moved from private section for some interactive stuff selA, selB: integer; // AV procedure UpdateDisplay(PreviewOnly: boolean = false); procedure UpdateFlame(bBgOnly: boolean = false); procedure CreateScreenShot; // AV end; var AdjustForm: TAdjustForm; function GradientInClipboard: boolean; procedure RGBToHSV(R, G, B: byte; var H, S, V: real); procedure HSVToRGB(H, S, V: real; var Rb, Gb, Bb: integer); implementation uses RndFlame, Main, cmapdata, Math, Browser, Editor, Global, // Curves, Save, Mutate, ClipBrd, GradientHlpr, Registry, ColorRangeForm; {$R *.DFM} procedure TAdjustForm.SetCurvesCp(ccp: TControlPoint); begin if CurvesControl = nil then Exit; CurvesControl.SetCp(ccp); end; procedure TAdjustForm.UpdateDisplay(PreviewOnly: boolean = false); var pw, ph: integer; r: double; begin cp.copy(MainCp); SetCurvesCp(MainCp); tbWeightLeft.Position := Round(CurvesControl.WeightLeft * 10); tbWeightRight.Position := Round(CurvesControl.WeightRight * 10); 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; cp.AdjustScale(PreviewImage.Width, PreviewImage.Height); cp.cmap := MainCp.cmap; if not PreviewOnly then begin //*** Resetting := True; // So the preview doesn't get drawn with these changes.. scrollGamma.Position := trunc(cp.Gamma * 100); scrollBrightness.Position := trunc(cp.Brightness * 100); scrollVibrancy.Position := trunc(cp.vibrancy * 100); scrollContrast.Position := trunc(cp.contrast * 100); // AV scrollZoom.Position := trunc(cp.zoom * 1000); scrollAngle.Position := Trunc(cp.FAngle * 18000.0 / PI) mod 36000; // scrollAngle.Max; if (abs(cp.Center[0]) < 1000) and (abs(cp.Center[1]) < 1000) then begin scrollCenterX.Position := trunc(cp.Center[0] * 1000); scrollCenterY.Position := trunc(cp.Center[1] * 1000); end else begin scrollCenterX.Position := 0; scrollCenterY.Position := 0; end; ColorPanel.color := cp.background[2] shl 16 + cp.background[1] shl 8 + cp.background[0]; Shape1.Brush.Color := ColorPanel.Color; //cbColor.text := IntToHex(integer(ColorPanel.Color), 6); GetMainWindowSize; // gradient if cp.cmapindex >= 0 then cmbPalette.ItemIndex := cp.cmapindex; ScrollBar.Position := 0; Palette := cp.cmap; BackupPal := cp.cmap; Resetting := False; editPPU.Text := Format('%.6g', [100*cp.pixels_per_unit/PreviewImage.Width]); txtGammaThreshold.Text := Format('%.3g', [cp.gammaThreshRelative]); // 3d camera txtPitch.Text := Format('%.6g', [cp.cameraPitch * 180 / PI]); txtYaw.Text := Format('%.6g', [cp.cameraYaw * 180 / PI]); txtRoll.Text := Format('%.6g', [cp.cameraRoll * 180 / PI]); // AV txtPersp.Text := Format('%.6g', [cp.cameraPersp]); txtZpos.Text := Format('%.6g', [cp.cameraZpos]); txtDOF.Text := Format('%.6g', [cp.cameraDof]); end; //*** DrawPreview; end; procedure TAdjustForm.UpdateFlame(bBgOnly: boolean = false); begin if not bBgOnly then MainForm.StopThread; MainForm.UpdateUndo; MainCp.Copy(cp, true); SetCurvesCp(cp); if EditForm.Visible then EditForm.UpdateDisplay; if MutateForm.Visible then MutateForm.UpdateDisplay; if bBgOnly then MainForm.tbShowAlphaClick(Self) else MainForm.RedrawTimer.enabled := true; end; procedure TAdjustForm.DrawPreview; var i: integer; Row: pRGBTripleArray; BitMap: TBitMap; procedure Draw3DAxes; // AV const w = 60; // default axis length var Origin, EndPoint, Rot: TPoint; sinPitch, cosPitch, sinRoll, cosRoll, sinYaw, cosYaw: double; sinA, cosA: double; DoRotate: boolean; begin SinCos(cp.cameraPitch, sinPitch, cosPitch); SinCos(cp.cameraRoll, sinRoll, cosRoll); SinCos(-cp.cameraYaw, sinYaw, cosYaw); if cp.FAngle <> 0 then begin SinCos(cp.FAngle, sinA, cosA); DoRotate := True; end else DoRotate := False; Origin.X := BM.Width shr 1; Origin.Y := BM.Height shr 1; with BM.Canvas do begin Pen.Width := 2; Font.Color := clBlack; // clWhite; // X - axis Pen.Color := clRed; Brush.Color := clRed; EndPoint.X := Round(cosRoll * cosYaw * w); EndPoint.Y := Round((sinPitch * sinRoll * cosYaw + cosPitch * sinYaw) * w); if DoRotate then begin Rot.X := Round(EndPoint.X * cosA + EndPoint.Y * sinA); Rot.Y := Round(-EndPoint.X * sinA + EndPoint.Y * cosA); EndPoint := Rot; end; MoveTo(Origin.X, Origin.Y); LineTo(Origin.X + EndPoint.X, Origin.Y + EndPoint.Y); TextOut(PenPos.X - 2, PenPos.Y - 2, 'X'); // Y - axis Pen.Color := clBlue; Brush.Color := clBlue; EndPoint.X := Round(-cosRoll * sinYaw * w); EndPoint.Y := Round((-sinPitch * sinRoll * sinYaw + cosPitch * cosYaw) * w); if DoRotate then begin Rot.X := Round(EndPoint.X * cosA + EndPoint.Y * sinA); Rot.Y := Round(-EndPoint.X * sinA + EndPoint.Y * cosA); EndPoint := Rot; end; MoveTo(Origin.X, Origin.Y); LineTo(Origin.X + EndPoint.X, Origin.Y + EndPoint.Y); TextOut(PenPos.X - 2, PenPos.Y - 2, 'Y'); // Z - axis Pen.Color := clGreen; Brush.Color := clGreen; EndPoint.X := Round(sinRoll * w); EndPoint.Y := Round(-sinPitch * cosRoll * w); if DoRotate then begin Rot.X := Round(EndPoint.X * cosA + EndPoint.Y * sinA); Rot.Y := Round(-EndPoint.X * sinA + EndPoint.Y * cosA); EndPoint := Rot; end; MoveTo(Origin.X, Origin.Y); LineTo(Origin.X + EndPoint.X, Origin.Y + EndPoint.Y); TextOut(PenPos.X - 2, PenPos.Y - 2, 'Z'); end; end; begin if Resetting then exit; Render.Stop; cp.sample_density := PreviewDensity; cp.spatial_oversample := defOversample; cp.spatial_filter_radius := defFilterRadius; Render.SetCP(cp); Render.Render; BM.Assign(Render.GetImage); if chkDisplay3DAxes.Checked then Draw3DAxes; // AV PreviewImage.Picture.Graphic := bm; if mnuInstantPreview.Checked then PreviewImage.Refresh; //--begin DrawPalette BitMap := TBitMap.Create; try Bitmap.PixelFormat := pf24bit; BitMap.Width := 256; BitMap.Height := 1; Row := Bitmap.Scanline[0]; for i := 0 to 255 do with Row[i] do begin rgbtRed := cp.cmap[i][0]; rgbtGreen := cp.cmap[i][1]; rgbtBlue := cp.cmap[i][2]; end; GradientImage.Picture.Graphic := Bitmap; GradientImage.Refresh; finally BitMap.Free; end; //--end DrawPalette end; procedure TAdjustForm.FormCreate(Sender: TObject); var ExtSM: HMenu; begin mnuCopy.Caption := TextByKey('common-copy'); mnuPaste.Caption := TextByKey('common-paste'); btnApplySize.Caption := TextByKey('common-apply'); mnuLowQuality.Caption := TextByKey('common-lowquality'); mnuMediumQuality.Caption := TextByKey('common-mediumquality'); mnuHighQuality.Caption := TextByKey('common-highquality'); btnCopy.Hint := TextByKey('adjustment-tab-gradient-copyhint'); btnPaste.Hint := TextByKey('adjustment-tab-gradient-pastehint'); btnSelected.Hint := TextByKey('adjustment-tab-gradient-selectedhint'); btnUndo.Hint := TextByKey('common-undo'); btnRedo.Hint := TextByKey('common-redo'); pnlWidth.Caption := TextByKey('common-width'); pnlHeight.Caption := TextByKey('common-height'); //chkMaintain.Caption := TextByKey('common-keepaspect'); cbAspectRatio.Items[0] := TextByKey('adjustment-tab-size-custom'); // AV cbAspectRatio.Items[1] := TextByKey('common-keepaspect'); // AV lblRatio.Caption := TextByKey('adjustment-tab-size-ratio'); pnlGamma.Caption := TextByKey('common-gamma'); pnlBrightness.Caption := TextByKey('common-brightness'); pnlVibrancy.Caption := TextByKey('common-vibrancy'); pnlContrast.Caption := TextByKey('common-contrast'); // AV pnlBackground.Caption := TextByKey('common-background'); pnlGammaThreshold.Caption := TextByKey('common-gammathreshold'); pnlDOF.Hint := TextByKey('common-dragpanelhint') + ' | ' + TextByKey('adjustment-hint-depthblur'); pnlPitch.Hint := TextByKey('common-dragpanelhint') + ' | ' + TextByKey('adjustment-hint-pitch'); pnlYaw.Hint := TextByKey('common-dragpanelhint') + ' | ' + TextByKey('adjustment-hint-yaw'); pnlRoll.Hint := TextByKey('common-dragpanelhint') + ' | ' + TextByKey('adjustment-hint-roll'); pnlZpos.Hint := TextByKey('common-dragpanelhint') + ' | ' + TextByKey('adjustment-hint-height'); pnlPersp.Hint := TextByKey('common-dragpanelhint') + ' | ' + TextByKey('adjustment-hint-perspective'); pnlMasterScale.Hint := TextByKey('common-dragpanelhint') + ' | ' + TextByKey('adjustment-hint-scale'); pnlZoom.Hint := TextByKey('common-dragpanelhint'); pnlXpos.Hint := TextByKey('common-dragpanelhint'); pnlYpos.Hint := TextByKey('common-dragpanelhint'); pnlAngle.Hint := TextByKey('common-dragpanelhint'); pnlGamma.Hint := TextByKey('common-dragpanelhint'); pnlBrightness.Hint := TextByKey('common-dragpanelhint'); pnlVibrancy.Hint := TextByKey('common-dragpanelhint'); pnlGammaThreshold.Hint := TextByKey('common-dragpanelhint'); self.Caption := TextByKey('adjustment-title'); pnlDOF.Caption := TextByKey('adjustment-common-depthblur'); pnlPitch.Caption := TextByKey('adjustment-common-pitch'); pnlYaw.Caption := TextByKey('adjustment-common-yaw'); pnlRoll.Caption := TextByKey('adjustment-common-roll'); pnlZpos.Caption := TextByKey('adjustment-common-height'); pnlPersp.Caption := TextByKey('adjustment-common-perspective'); pnlMasterScale.Caption := TextByKey('adjustment-common-scale'); TabCamera.Caption := TextByKey('adjustment-tab-camera-title'); pnlZoom.Caption := TextByKey('adjustment-tab-camera-zoom'); pnlXPos.Caption := TextByKey('adjustment-tab-camera-xpos'); pnlYPos.Caption := TextByKey('adjustment-tab-camera-ypos'); pnlAngle.Caption := TextByKey('adjustment-tab-camera-rotation'); btResetZoom.Caption := TextByKey('adjustment-tab-camera-resetzoom'); chkDisplay3DAxes.Caption := TextByKey('adjustment-tab-camera-draw3daxes'); btResetZoom.Hint := TextByKey('adjustment-hint-resetzoom'); TabRendering.Caption := TextByKey('adjustment-tab-rendering-title'); TabGradient.Caption := TextByKey('adjustment-tab-gradient-title'); mnuRotate.Caption := TextByKey('adjustment-tab-gradient-moderotate'); mnuHue.Caption := TextByKey('adjustment-tab-gradient-modehue'); mnuSaturation.Caption := TextByKey('adjustment-tab-gradient-modesaturation'); mnuBrightness.Caption := TextByKey('adjustment-tab-gradient-modebrightness'); mnuLuminance.Caption := TextByKey('adjustment-tab-gradient-modeluminance'); Contrast1.Caption := TextByKey('adjustment-tab-gradient-modecontrast'); mnuBlur.Caption := TextByKey('adjustment-tab-gradient-modeblur'); mnuFrequency.Caption := TextByKey('adjustment-tab-gradient-modefrequency'); btnColorPreset.Caption := TextByKey('adjustment-tab-gradient-preset'); btnColorPreset.Hint := TextByKey('adjustment-tab-gradient-presethint'); btnReset.Caption := TextByKey('adjustment-tab-gradient-reset'); btnMenu.Hint := TextByKey('adjustment-tab-gradient-modehint'); GradientImage.Hint := StringReplace(TextByKey('adjustment-tab-gradient-palettehint'), ',', ','#13, [rfReplaceAll]); btnSet1.Hint := TextByKey('adjustment-tab-size-savepreset'); btnSet2.Hint := TextByKey('adjustment-tab-size-savepreset'); btnSet3.Hint := TextByKey('adjustment-tab-size-savepreset'); TabSize.Caption := TextByKey('adjustment-tab-size-title'); btnPreset1.Hint := TextByKey('adjustment-tab-size-preset'); btnPreset2.Hint := TextByKey('adjustment-tab-size-preset'); btnPreset3.Hint := TextByKey('adjustment-tab-size-preset'); TabCurves.Caption := TextByKey('adjustment-tab-curves-title'); btnResetCurves.Caption := TextByKey('adjustment-tab-curves-reset'); Panel5.Caption := TextByKey('adjustment-tab-curves-selected'); cbChannel.Items[0] := TextByKey('adjustment-tab-curves-overall'); cbChannel.Items[1] := TextByKey('adjustment-tab-curves-red'); cbChannel.Items[2] := TextByKey('adjustment-tab-curves-green'); cbChannel.Items[3] := TextByKey('adjustment-tab-curves-blue'); chkResizeMain.Caption := TextByKey('adjustment-tab-size-resizemain'); mnuInstantPreview.Caption := TextByKey('adjustment-popup-quality-instantpreview'); mnuRandomize.Caption := TextByKey('adjustment-popup-gradient-randomize'); mnuInvert.Caption := TextByKey('adjustment-popup-gradient-invert'); mnuReverse.Caption := TextByKey('adjustment-popup-gradient-reverse'); mnuSepia.Caption := TextByKey('adjustment-popup-gradient-sepia'); mnuSmoothPalette.Caption := TextByKey('adjustment-popup-gradient-smooth'); btnSmoothPalette.Hint := TextByKey('main-menu-file-smoothpalettehint'); mnuGradientBrowser.Caption := TextByKey('adjustment-popup-gradient-browser'); btnOpen.Hint := TextByKey('adjustment-popup-gradient-browser'); SaveGradient1.Caption := TextByKey('adjustment-popup-gradient-saveasugr'); SaveasMapfile1.Caption := TextByKey('adjustment-popup-gradient-saveasmap'); mnuSaveAsDefault.Caption := TextByKey('adjustment-popup-gradient-saveasdefault'); SaveAsScript.Caption := TextByKey('adjustment-popup-gradient-saveasscript'); btnMenu.Caption := TextByKey('adjustment-tab-gradient-moderotate'); Red1.Caption := TextByKey('adjustment-tab-curves-red'); Green1.Caption := TextByKey('adjustment-tab-curves-green'); Blue1.Caption := TextByKey('adjustment-tab-curves-blue'); Smoothize1.Caption := TextByKey('adjustment-popup-gradient-smoothize'); SmoothizeSelected.Caption := TextByKey('adjustment-popup-gradient-smoothizesel'); LerpRGB.Caption := TextByKey('adjustment-popup-gradient-interprgb'); LerpHSV.Caption := TextByKey('adjustment-popup-gradient-interphsv'); mnuRGB2BGR.Caption := TextByKey('adjustment-popup-gradient-swaprgb'); mnuSetColor.Caption := TextByKey('adjustment-popup-gradient-setcolor'); RandomizeSelected.Caption := TextByKey('adjustment-popup-gradient-randomizesel'); InvertColors.Caption := TextByKey('adjustment-popup-gradient-invertsel'); ReverseFragment.Caption := TextByKey('adjustment-popup-gradient-reversesel'); MixColors.Caption := TextByKey('adjustment-popup-gradient-mixcolors'); CopyFragment1.Caption := TextByKey('adjustment-popup-gradient-copysel'); PasteFragment1.Caption := TextByKey('adjustment-popup-gradient-pastesel'); mnuGreyscale.Caption := TextByKey('adjustment-popup-gradient-grayscale'); RemoveDarkAreas1.Caption := TextByKey('adjustment-popup-gradient-removedark'); SymmetricGradient1.Caption := TextByKey('adjustment-popup-gradient-symmetry'); FlipLeftHalf1.Caption := TextByKey('adjustment-popup-gradient-flipleft'); FlipRightHalf1.Caption := TextByKey('adjustment-popup-gradient-flipright'); AdjustSelected.Caption := TextByKey('adjustment-popup-gradient-adjustbyslider'); AdjustColorFragment.Caption := TextByKey('adjustment-popup-gradient-adjustfragment'); gbSize.Caption := TextByKey('common-pixels'); gbPresets.Caption := TextByKey('adjustment-tab-size-presets'); gbChange.Caption := TextByKey('adjustment-tab-size-output'); ExtSM := GetSystemMenu(Handle, False); // AV InsertMenu(ExtSM, UINT(5), MF_ByPosition or MF_Separator, 0, nil); InsertMenu(ExtSM, UINT(6), MF_ByPosition, $C0, PChar(TextByKey('main-menu-screenshot'))); cbChannel.ItemIndex := 0; cbAspectRatio.ItemIndex := 0; if not (assigned(curvesControl)) then begin CurvesControl := TCurvesControl.Create(self); CurvesControl.Align := alClient; CurvesControl.Parent := CurvesPanel; end; tbWeightLeft.Position := Round(CurvesControl.WeightLeft * 10); tbWeightRight.Position := Round(CurvesControl.WeightRight * 10); bm := TbitMap.Create; cp := TControlPoint.Create; Render := TRenderer.Create; case AdjustPrevQual 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; Sendmessage(cmbPalette.Handle, CB_SETDROPPEDWIDTH , cmbPalette.width * 2, 0); SetCurvesCp(MainCp); selA := 0; selB := 255; // AV end; procedure TAdjustForm.FormClose(Sender: TObject; var Action: TCloseAction); var Registry: TRegistry; begin Render.Stop; { Write position to registry } Registry := TRegistry.Create; try Registry.RootKey := HKEY_CURRENT_USER; if Registry.OpenKey('\Software\' + APP_NAME + '\Forms\Adjust', True) then begin Registry.WriteInteger('Top', AdjustForm.Top); Registry.WriteInteger('Left', AdjustForm.Left); Registry.WriteBool('InstantPreview', mnuInstantPreview.Checked); Registry.WriteBool('ResizeMain', chkResizeMain.Checked); Registry.WriteBool('Display3DAxes', chkDisplay3DAxes.Checked); // AV end; finally Registry.Free; end; end; procedure TAdjustForm.FormDestroy(Sender: TObject); begin bm.free; cp.free; Render.free; end; procedure TAdjustForm.FormShow(Sender: TObject); var Registry: TRegistry; i: integer; strx, stry, strw, strh: string; begin if LimitVibrancy then scrollVibrancy.Max := 100 else scrollVibrancy.Max := 3000; { Read position from registry } Registry := TRegistry.Create; try Registry.RootKey := HKEY_CURRENT_USER; if Registry.OpenKey('Software\' + APP_NAME + '\Forms\Adjust', False) then begin if Registry.ValueExists('Left') then AdjustForm.Left := Registry.ReadInteger('Left'); if Registry.ValueExists('Top') then AdjustForm.Top := Registry.ReadInteger('Top'); if Registry.ValueExists('InstantPreview') then mnuInstantPreview.Checked := Registry.ReadBool('InstantPreview'); if Registry.ValueExists('ResizeMain') then chkResizeMain.Checked := Registry.ReadBool('ResizeMain'); if Registry.ValueExists('Display3DAxes') then // AV chkDisplay3DAxes.Checked := Registry.ReadBool('Display3DAxes'); Registry.CloseKey; end; if Registry.OpenKey('Software\' + APP_NAME + '\ImageSizePresets', False) then begin for i := 1 to 3 do begin strx:='Preset' + IntToStr(i) + 'Left'; stry:='Preset' + IntToStr(i) + 'Top'; strw:='Preset' + IntToStr(i) + 'Width'; strh:='Preset' + IntToStr(i) + 'Height'; if Registry.ValueExists(strw) and Registry.ValueExists(strh) then begin Preset[i].Left := Registry.ReadInteger(strx); Preset[i].Top := Registry.ReadInteger(stry); Preset[i].Width := Registry.ReadInteger(strw); Preset[i].Height := Registry.ReadInteger(strh); if (Preset[1].Width > 0) and (Preset[1].Height > 0) then continue; end; Preset[i].Left := MainForm.Left; Preset[i].Top := MainForm.Top; // AV: make them different by default case i of 1: begin Preset[1].Width := 512; Preset[1].Height := 384; end; 2: begin Preset[2].Width := 640; Preset[2].Height := 480; end; 3: begin Preset[3].Width := 800; Preset[3].Height := 600; end; end; // end case end; end else begin for i := 1 to 3 do begin Preset[i].Left := MainForm.Left; Preset[i].Top := MainForm.Top; end; // AV: make them different by default Preset[1].Width := 512; Preset[1].Height := 384; Preset[2].Width := 640; Preset[2].Height := 480; Preset[3].Width := 800; Preset[3].Height := 600; end; Registry.CloseKey; finally Registry.Free; end; GetMainWindowSize; btnPreset1.Caption := PresetToStr(1); btnPreset2.Caption := PresetToStr(2); btnPreset3.Caption := PresetToStr(3); end; /////////////////////////////////////////////////// procedure TAdjustForm.CreateScreenShot; begin SaveScreenShot('Apophysis Adjustment Window'); end; procedure TAdjustForm.ExtSysMenu(var Msg: TMessage); begin if Msg.WParam = $C0 then CreateScreenShot; inherited; end; ////////////////////////////////////////////////// procedure TAdjustForm.mnuLowQualityClick(Sender: TObject); begin mnuLowQuality.Checked := True; PreviewDensity := prevLowQuality; AdjustPrevQual := 0; DrawPreview; end; procedure TAdjustForm.mnuMediumQualityClick(Sender: TObject); begin mnuMediumQuality.Checked := True; PreviewDensity := prevMediumQuality; AdjustPrevQual := 1; DrawPreview; end; procedure TAdjustForm.mnuHighQualityClick(Sender: TObject); begin mnuHighQuality.Checked := True; PreviewDensity := prevHighQuality; AdjustPrevQual := 2; DrawPreview; end; procedure TAdjustForm.chkDisplay3DAxesClick(Sender: TObject); // AV begin DrawPreview; // show or hide coordinate axes end; procedure TAdjustForm.txtZoomEnter(Sender: TObject); begin EditBoxValue := txtZoom.Text; end; procedure TAdjustForm.txtZoomKeyPress(Sender: TObject; var Key: Char); begin if (Key = ',') then Key := '.'; if not CharinSet(Key,['0'..'9', #8, #13, '.']) then Key:= #0; if ((key = #13) and (EditBoxValue <> txtZoom.Text)) then begin key := #0; txtZoomExit(sender); end; end; procedure TAdjustForm.txtZoomExit(Sender: TObject); var v: integer; begin if (EditBoxValue <> txtZoom.Text) then try v := Trunc(StrToFloat(txtZoom.Text) * 1000); if v > scrollZoom.Max then v := scrollZoom.Max; if v < scrollZoom.Min then v := scrollZoom.Min; if v <> ScrollZoom.Position then begin ScrollZoom.Position := v; UpdateFlame; end; except on EConvertError do txtZoom.Text := FloatToStr(cp.zoom) end; end; procedure TAdjustForm.txtCenterXEnter(Sender: TObject); begin EditBoxValue := txtCenterX.Text; end; procedure TAdjustForm.txtCenterXKeyPress(Sender: TObject; var Key: Char); begin if (Key = ',') then Key := '.'; if not CharinSet(Key,['0'..'9','-', #8, #13, '.']) then Key:= #0; if ((key = #13) and (EditBoxValue <> txtCenterX.Text)) then begin key := #0; txtCenterXExit(sender); end; end; procedure TAdjustForm.txtCenterXExit(Sender: TObject); var v: integer; begin if (EditBoxValue <> txtCenterX.Text) then try v := Trunc(StrToFloat(txtCenterX.Text) * 1000); if v > scrollCenterX.Max then v := scrollCenterX.Max; if v < scrollCenterX.Min then v := scrollCenterX.Min; ScrollCenterX.Position := v; UpdateFlame; except on EConvertError do txtCenterX.Text := FloatToStr(cp.center[0]); end; end; procedure TAdjustForm.txtCenterYEnter(Sender: TObject); begin EditBoxValue := txtCenterY.Text; end; procedure TAdjustForm.txtCenterYKeyPress(Sender: TObject; var Key: Char); begin if (Key = ',') then Key := '.'; if not CharinSet(Key,['0'..'9','-', #8, #13, '.']) then Key:= #0; if ((key = #13) and (EditBoxValue <> txtCenterY.Text)) then begin key := #0; txtCenterYExit(sender); end; end; procedure TAdjustForm.txtContrastEnter(Sender: TObject); begin EditBoxValue := txtContrast.Text; end; procedure TAdjustForm.txtContrastExit(Sender: TObject); var v: integer; begin if (txtContrast.Text <> EditBoxValue) then try v := Trunc(StrToFloat(txtContrast.Text) * 100); if v > scrollContrast.Max then v := scrollContrast.Max; if v < scrollContrast.Min then v := scrollContrast.Min; ScrollContrast.Position := v; UpdateFlame; except on EConvertError do txtContrast.Text := FloatToStr(cp.Contrast); end; end; procedure TAdjustForm.txtContrastKeyPress(Sender: TObject; var Key: Char); begin if (Key = ',') then Key := '.'; //FormatSettings.DecimalSeparator; if not CharinSet(Key,['0'..'9', #8, #13, '.']) then Key:= #0; if ((key = #13) and (txtContrast.Text <> EditBoxValue)) then begin key := #0; txtContrastExit(sender); end; end; procedure TAdjustForm.txtCenterYExit(Sender: TObject); var v: integer; begin if (EditBoxValue <> txtCenterY.Text) then try v := Trunc(StrToFloat(txtCenterY.Text) * 1000); if v > ScrollCenterY.Max then v := ScrollCenterY.Max; if v < ScrollCenterY.Min then v := ScrollCenterY.Min; ScrollCenterY.Position := v; UpdateFlame; except on EConvertError do txtCenterY.Text := FloatToStr(cp.center[1]); end; end; procedure TAdjustForm.txtGammaEnter(Sender: TObject); begin EditBoxValue := txtGamma.Text; end; procedure TAdjustForm.txtGammaExit(Sender: TObject); var v: integer; begin if (txtGamma.Text <> EditBoxValue) then try v := Trunc(StrToFloat(txtGamma.Text) * 100); if v > scrollGamma.Max then v := scrollGamma.Max; if v < scrollGamma.Min then v := scrollGamma.Min; ScrollGamma.Position := v; UpdateFlame; except on EConvertError do txtGamma.Text := FloatToStr(cp.gamma); end; end; procedure TAdjustForm.txtGammaKeyPress(Sender: TObject; var Key: Char); begin if (Key = ',') then Key := '.'; //FormatSettings.DecimalSeparator; if not CharinSet(Key,['0'..'9', #8, #13, '.']) then Key:= #0; if ((key = #13) and (txtGamma.Text <> EditBoxValue)) then begin key := #0; txtGammaExit(sender); end; end; procedure TAdjustForm.txtBrightnessEnter(Sender: TObject); begin EditBoxValue := txtBrightness.Text; end; procedure TAdjustForm.txtBrightnessExit(Sender: TObject); var v: integer; begin if (txtBrightness.Text <> EditBoxValue) then try v := Trunc(StrToFloat(txtBrightness.Text) * 100); if v > scrollBrightness.Max then v := scrollBrightness.Max; if v < scrollBrightness.Min then v := scrollBrightness.Min; ScrollBrightness.Position := v; UpdateFlame; except on EConvertError do txtBrightness.Text := FloatToStr(cp.brightness); end; end; procedure TAdjustForm.txtBrightnessKeyPress(Sender: TObject; var Key: Char); begin if (Key = ',') then Key := '.'; //FormatSettings.DecimalSeparator; if not CharinSet(Key,['0'..'9', #8, #13, '.']) then Key:= #0; if ((key = #13) and (txtBrightness.Text <> EditBoxValue)) then begin key := #0; txtBrightnessExit(sender); end; end; procedure TAdjustForm.txtVibrancyEnter(Sender: TObject); begin EditBoxValue := txtVibrancy.Text; end; procedure TAdjustForm.txtVibrancyKeyPress(Sender: TObject; var Key: Char); begin if (Key = ',') then Key := '.'; if not CharinSet(Key,['0'..'9', #8, #13, '.']) then Key:= #0; if ((key = #13) and (txtVibrancy.Text <> EditBoxValue)) then begin key := #0; txtVibrancyExit(sender); end; end; procedure TAdjustForm.txtVibrancyExit(Sender: TObject); var v: integer; begin if (txtVibrancy.Text <> EditBoxValue) then try v := Trunc(StrToFloat(txtVibrancy.Text) * 100); if v > scrollVibrancy.Max then v := scrollVibrancy.Max; if v < scrollVibrancy.Min then v := scrollVibrancy.Min; ScrollVibrancy.Position := v; UpdateFlame; except on EConvertError do txtVibrancy.Text := FloatToStr(cp.Vibrancy); end; end; procedure TAdjustForm.scrollCameraScroll(Sender: TObject; ScrollCode: TScrollCode; var ScrollPos: Integer); begin if ScrollCode = scEndScroll then UpdateFlame; end; procedure TAdjustForm.scrollVibrancyScroll(Sender: TObject); begin cp.Vibrancy := ScrollVibrancy.Position / 100; txtVibrancy.text := FloatToStr(cp.Vibrancy); txtVibrancy.Refresh; DrawPreview; end; procedure TAdjustForm.scrollGammaChange(Sender: TObject); begin cp.Gamma := scrollGamma.Position / 100; txtGamma.text := FloatToStr(cp.Gamma); txtGamma.Refresh; DrawPreview; end; procedure TAdjustForm.scrollBrightnessChange(Sender: TObject); begin cp.Brightness := ScrollBrightness.Position / 100; txtBrightness.text := FloatToStr(cp.Brightness); txtBrightness.Refresh; DrawPreview; end; procedure TAdjustForm.scrollZoomChange(Sender: TObject); begin cp.zoom := scrollZoom.Position / 1000; txtZoom.text := FloatToStr(cp.zoom); txtZoom.Refresh; DrawPreview; end; procedure TAdjustForm.scrollCenterXChange(Sender: TObject); begin cp.center[0] := scrollCenterX.Position / 1000; txtCenterX.text := FloatToStr(cp.center[0]); txtCenterX.Refresh; DrawPreview; end; procedure TAdjustForm.scrollCenterYChange(Sender: TObject); begin cp.center[1] := scrollCenterY.Position / 1000; txtCenterY.text := FloatToStr(cp.center[1]); txtCenterY.Refresh; DrawPreview; end; procedure TAdjustForm.scrollContrastChange(Sender: TObject); begin cp.Contrast := ScrollContrast.Position / 100; txtContrast.text := FloatToStr(cp.Contrast); txtContrast.Refresh; DrawPreview; end; procedure TAdjustForm.ColorPanelClick(Sender: TObject); var col: Longint; begin ColorDialog.Color := ColorPanel.Color; if ColorDialog.Execute then begin ColorPanel.Color := ColorDialog.Color; Shape1.Brush.Color := ColorPanel.Color; //cbColor.text := IntToHex(integer(ColorDialog.Color), 6); col := ColorToRGB(ColorDialog.Color); cp.background[0] := col and 255; cp.background[1] := col shr 8 and 255; cp.background[2] := col shr 16 and 255; DrawPreview; UpdateFlame(true); end; end; procedure TAdjustForm.Copyfragment1Click(Sender: TObject); var i, j: integer; begin SetLength(tmpColors, selB - selA + 1, 3); for i := 0 to selB - selA do for j := 0 to 2 do tmpColors[i, j] := palette[i + selA, j]; PasteFragment1.Enabled := true; MixColors.Enabled := true; end; procedure TAdjustForm.curveChange(Sender: TObject); begin if CurvesControl = nil then Exit; CurvesControl.ActiveChannel := TCurvesChannel(cbChannel.ItemIndex); tbWeightLeft.Position := Round(cp.curveWeights[cbChannel.ItemIndex][1] * 10); //Round(CurvesControl.WeightLeft * 10); tbWeightRight.Position := Round(cp.curveWeights[cbChannel.ItemIndex][2] * 10); //Round(CurvesControl.WeightRight * 10); end; procedure TAdjustForm.scrollAngleChange(Sender: TObject); begin cp.FAngle := scrollAngle.Position * PI / 18000.0; txtAngle.text := FloatToStr(cp.FAngle * 180 / PI); txtAngle.Refresh; DrawPreview; end; (* procedure TAdjustForm.scrollAngleScroll(Sender: TObject; ScrollCode: TScrollCode; var ScrollPos: Integer); begin if ScrollCode = scEndScroll then UpdateFlame; end; *) procedure TAdjustForm.txtAngleEnter(Sender: TObject); begin EditBoxValue := txtAngle.Text; end; procedure TAdjustForm.txtAngleKeyPress(Sender: TObject; var Key: Char); var v: integer; begin if (Key = ',') then Key := '.'; if not CharinSet(Key,['0'..'9','-', #8, #13, '.']) then Key:= #0; if ((key = #13) and (txtAngle.Text <> EditBoxValue)) then begin key := #0; try v := Trunc(StrToFloat(txtAngle.Text) * 100) mod scrollAngle.Max; //if v > scrollAngle.Max then v := v - scrollAngle.Max*2 if v < scrollAngle.Min then v := v + scrollAngle.Max; ScrollAngle.Position := v; UpdateFlame; EditBoxValue := txtAngle.Text; except on EConvertError do end; end; end; procedure TAdjustForm.txtAngleExit(Sender: TObject); var v: integer; begin if (txtAngle.Text <> EditBoxValue) then try v := Trunc(StrToFloat(txtAngle.Text) * 100) mod scrollAngle.Max; // if v > scrollAngle.Max then v := v - scrollAngle.Max*2 // else if v < scrollAngle.Min then v := v + scrollAngle.Max*2; ScrollAngle.Position := v; UpdateFlame; except on EConvertError do txtAngle.Text := FloatToStr(cp.FAngle * 180 / PI); end; end; // --Z-- // gradient stuff implementation -------------------------------------- procedure TAdjustForm.Apply; begin MainForm.StopThread; MainForm.UpdateUndo; MainCp.CmapIndex := cmbPalette.ItemIndex; MainCp.cmap := Palette; SetCurvesCp(MainCp); if EditForm.visible then EditForm.UpdateDisplay; if MutateForm.Visible then MutateForm.UpdateDisplay; if mnuInstantPreview.Checked then DrawPreview; if GradStatusBar.Panels[2].Text <> '' then GradStatusBar.Refresh; // AV MainForm.RedrawTimer.enabled := true; end; procedure TAdjustForm.SaveMap(FileName: string); var i: Integer; l: string; MapFile: TextFile; begin { Save a map file } AssignFile(MapFile, FileName); try ReWrite(MapFile); { first line with comment } l := Format(' %3d %3d %3d Exported from Apophysis 2.0', [Palette[0][0], palette[0][1], palette[0][2]]); Writeln(MapFile, l); { now the rest } for i := 1 to 255 do begin l := Format(' %3d %3d %3d', [Palette[i][0], palette[i][1], palette[i][2]]); Writeln(MapFile, l); end; CloseFile(MapFile); except on EInOutError do raise Exception.CreateFmt(TextByKey('common-genericopenerror'), [FileName]); // AV end; end; procedure TAdjustForm.UpdateGradient(Pal: TColorMap); begin ScrollBar.Position := 0; Palette := Pal; BackupPal := Pal; // DrawPalette; cp.cmap := pal; // cp.copy(MainCp); if mnuInstantPreview.Checked then DrawPreview; end; procedure HSVToRGB(H, S, V: real; var Rb, Gb, Bb: integer); var R, G, B, Sa, Va, Hue, i, f, p, q, t: real; begin R := 0; G := 0; B := 0; Sa := S / 100; Va := V / 100; if S = 0 then begin R := Va; G := Va; B := Va; end else begin Hue := H / 60; if Hue = 6 then Hue := 0; i := Int(Hue); f := Hue - i; p := Va * (1 - Sa); q := Va * (1 - (Sa * f)); t := Va * (1 - (Sa * (1 - f))); case Round(i) of 0: begin R := Va; G := t; B := p; end; 1: begin R := q; G := Va; B := p; end; 2: begin R := p; G := Va; B := t; end; 3: begin R := p; G := q; B := Va; end; 4: begin R := t; G := p; B := Va; end; 5: begin R := Va; G := p; B := q; end; end; end; Rb := Round(Int(255.9999 * R)); Gb := Round(Int(255.9999 * G)); Bb := Round(Int(255.9999 * B)); end; procedure RGBToHSV(R, G, B: byte; var H, S, V: real); var vRed, vGreen, vBlue, Mx, Mn, Va, Sa, rc, gc, bc: real; begin vRed := R / 255; vGreen := G / 255; vBlue := B / 255; Mx := vRed; if vGreen > Mx then Mx := vGreen; if vBlue > Mx then Mx := vBlue; Mn := vRed; if vGreen < Mn then Mn := vGreen; if vBlue < Mn then Mn := vBlue; Va := Mx; if Mx <> 0 then Sa := (Mx - Mn) / Mx else Sa := 0; if Sa = 0 then H := 0 else begin rc := (Mx - vRed) / (Mx - Mn); gc := (Mx - vGreen) / (Mx - Mn); bc := (Mx - vBlue) / (Mx - Mn); if Mx = vRed then H := bc - gc else if Mx = vGreen then H := 2 + rc - bc else if Mx = vBlue then H := 4 + gc - rc; H := H * 60; if H < 0 then H := H + 360; end; S := Sa * 100; V := Va * 100; end; function TAdjustForm.Blur(const Radius: Integer; const pal: TColorMap; start, last: byte): TColorMap; var r, g, b, n, i, j, k: Integer; begin Result := Pal; if Radius <> 0 then for i := start to last do // AV: changed from 0 - 255 begin n := -1; r := 0; g := 0; b := 0; for j := i - radius to i + radius do begin inc(n); k := (256 + j) mod 256; if k <> i then begin r := r + Pal[k][0]; g := g + Pal[k][1]; b := b + Pal[k][2]; end; end; if n <> 0 then begin Result[i][0] := r div n; Result[i][1] := g div n; Result[i][2] := b div n; end; end; end; function TAdjustForm.Frequency(const times: Integer; const pal: TColorMap): TColorMap; { This can be improved } var n, i, j: Integer; begin Result := Pal; if times <> 1 then begin n := 256 div times; for j := 0 to times do for i := 0 to n do begin if ((i + j * n) < 256) and ((i * times) < 256) then begin Result[i + j * n][0] := pal[i * times][0]; Result[i + j * n][1] := pal[i * times][1]; Result[i + j * n][2] := pal[i * times][2]; end; end; end; end; function TAdjustForm.FrequencySel(const times: Integer; const pal: TColorMap): TColorMap; var n, i, j, k: Integer; begin Result := Pal; if times <> 1 then begin n := (selB - selA + 1) div times; for j := 0 to times do for i := 0 to n-1 do begin k := selA + i + j * n; if k > selB then break; Result[k][0] := pal[selA + i * times][0]; Result[k][1] := pal[selA + i * times][1]; Result[k][2] := pal[selA + i * times][2]; end; end; end; procedure TAdjustForm.cmbPaletteChange(Sender: TObject); var i: integer; begin if Resetting then exit; i := cmbPalette.ItemIndex; GetCmap(i, 1, Palette); BackupPal := Palette; ScrollBar.Position := 0; //DrawPalette; // MainForm.UpdateUndo; Apply; GradStatusBar.Refresh; end; procedure TAdjustForm.mnuRedClick(Sender: TObject); begin btnMenu.Caption := TextByKey('adjustment-tab-curves-red'); scrollMode := modeRed; BackupPal := Palette; ScrollBar.Min := -255; ScrollBar.Max := 255; ScrollBar.LargeChange := 15; ScrollBar.Position := 0; end; procedure TAdjustForm.mnuGreenClick(Sender: TObject); begin btnMenu.Caption := TextByKey('adjustment-tab-curves-green'); scrollMode := modeGreen; BackupPal := Palette; ScrollBar.Min := -255; ScrollBar.Max := 255; ScrollBar.LargeChange := 15; ScrollBar.Position := 0; end; procedure TAdjustForm.mnuGreyscaleClick(Sender: TObject); var i, j, grey: integer; begin for i := 0 to 255 do begin grey := Round(0.3 * Palette[i,0] + 0.59 * Palette[i,1] + 0.11 * Palette[i,2]); for j := 0 to 2 do Palette[i][j] := grey; end; UpdateGradient(palette); // MainForm.UpdateUndo; Apply; end; procedure TAdjustForm.mnuBlueClick(Sender: TObject); begin btnMenu.Caption := TextByKey('adjustment-tab-curves-blue'); scrollMode := modeBlue; BackupPal := Palette; ScrollBar.Min := -255; ScrollBar.Max := 255; ScrollBar.LargeChange := 15; ScrollBar.Position := 0; end; procedure TAdjustForm.mnuReverseClick(Sender: TObject); var i: integer; pal: TColorMap; begin for i := 0 to 255 do begin pal[i][0] := Palette[255 - i][0]; pal[i][1] := Palette[255 - i][1]; pal[i][2] := Palette[255 - i][2]; end; UpdateGradient(pal); // MainForm.UpdateUndo; Apply; end; procedure TAdjustForm.mnuRGB2BGRClick(Sender: TObject); var i, j, r, g, b: integer; pal: array of array of byte; begin case TMenuItem(Sender).Tag of 0: begin r := 2; g := 1; b := 0; end; 1: begin r := 1; g := 2; b := 0; end; 2: begin r := 0; g := 2; b := 1; end; 3: begin r := 1; g := 0; b := 2; end; 4: begin r := 2; g := 0; b := 1; end; else begin r := 0; g := 1; b := 2; end; end; SetLength(pal, selB - selA + 1, 3); for i := 0 to selB - selA do begin pal[i][0] := Palette[i + selA][r]; pal[i][1] := Palette[i + selA][g]; pal[i][2] := Palette[i + selA][b]; end; for i := 0 to selB - selA do for j := 0 to 2 do Palette[i + selA][j] := Pal[i][j]; UpdateGradient(palette); Apply; end; procedure TAdjustForm.mnuInvertClick(Sender: TObject); var i: integer; begin for i := 0 to 255 do begin Palette[i][0] := 255 - Palette[i][0]; Palette[i][1] := 255 - Palette[i][1]; Palette[i][2] := 255 - Palette[i][2]; end; UpdateGradient(palette); // MainForm.UpdateUndo; Apply; end; procedure TAdjustForm.btnMenuClick(Sender: TObject); begin scrollModePopup.Popup(btnMenu.ClientOrigin.x, btnMenu.ClientOrigin.y + btnMenu.Height); end; procedure TAdjustForm.ScrollBarChange(Sender: TObject); var intens, i, r, g, b, lab: integer; na, nb: byte; h, s, v: real; begin txtVal.Text := IntToStr(ScrollBar.Position); txtVal.Refresh; if Resetting then exit; GradientChanged:=true; // hmm // AV: allow user to manipulate the palette's segment if not AdjustSelected.Checked then begin na := 0; nb := 255; end else begin na := selA; nb := selB; end; case scrollMode of modeHue: for i := na to nb do begin RGBToHSV(BackupPal[i][0], BackupPal[i][1], BackupPal[i][2], h, s, v); if s <> 0 then // --Z-- (?) // AV: when saturation = 0, hue doesn't matter begin h := Round(360 + h + ScrollBar.Position) mod 360; HSVToRGB(h, s, v, Palette[i][0], Palette[i][1], Palette[i][2]); end; end; modeSaturation: for i := na to nb do begin RGBToHSV(BackupPal[i][0], BackupPal[i][1], BackupPal[i][2], h, s, v); if s <> 0 then // --Z-- //(?) begin s := s + ScrollBar.Position; if s > 100 then s := 100; if s < 0 then s := 0; HSVToRGB(h, s, v, Palette[i][0], Palette[i][1], Palette[i][2]); end; end; modeLuminance: // AV for i := na to nb do begin RGBToHSV(BackupPal[i][0], BackupPal[i][1], BackupPal[i][2], h, s, v); v := v + ScrollBar.Position; if v > 100 then v := 100; if v < 0 then v := 0; HSVToRGB(h, s, v, Palette[i][0], Palette[i][1], Palette[i][2]); end; modeContrast: begin intens := scrollBar.Position; if intens > 0 then intens := intens * 2; for i := na to nb do begin r := BackupPal[i][0]; g := BackupPal[i][1]; b := BackupPal[i][2]; r := round(r + intens / 100 * (r - 127)); g := round(g + intens / 100 * (g - 127)); b := round(b + intens / 100 * (b - 127)); if R > 255 then R := 255 else if R < 0 then R := 0; if G > 255 then G := 255 else if G < 0 then G := 0; if B > 255 then B := 255 else if B < 0 then B := 0; Palette[i][0] := r; Palette[i][1] := g; Palette[i][2] := b; end; end; modeBrightness: for i := na to nb do begin Palette[i][0] := BackupPal[i][0] + ScrollBar.Position; if Palette[i][0] > 255 then Palette[i][0] := 255; if Palette[i][0] < 0 then Palette[i][0] := 0; Palette[i][1] := BackupPal[i][1] + ScrollBar.Position; if Palette[i][1] > 255 then Palette[i][1] := 255; if Palette[i][1] < 0 then Palette[i][1] := 0; Palette[i][2] := BackupPal[i][2] + ScrollBar.Position; if Palette[i][2] > 255 then Palette[i][2] := 255; if Palette[i][2] < 0 then Palette[i][2] := 0; end; modeRotate: if not AdjustSelected.Checked then begin ScrollBar.Min := -128; ScrollBar.Max := 128; ScrollBar.LargeChange := 16; for i := 0 to 255 do begin Palette[i][0] := BackupPal[(256 + i - ScrollBar.Position) mod 256][0]; Palette[i][1] := BackupPal[(256 + i - ScrollBar.Position) mod 256][1]; Palette[i][2] := BackupPal[(256 + i - ScrollBar.Position) mod 256][2]; end; end else begin lab := selB - selA + 1; if lab > 255 then lab := 255; ScrollBar.Max := lab; ScrollBar.Min := -lab; ScrollBar.LargeChange := 2; if ScrollBar.Position > 0 then for i := na to nb do begin lab := i - ScrollBar.Position; if lab < selA then lab := lab + nb - na + 1; Palette[i][0] := BackupPal[lab][0]; Palette[i][1] := BackupPal[lab][1]; Palette[i][2] := BackupPal[lab][2]; end else for i := na to nb do begin lab := i - ScrollBar.Position; if lab > selB then lab := lab - nb + na - 1; Palette[i][0] := BackupPal[lab][0]; Palette[i][1] := BackupPal[lab][1]; Palette[i][2] := BackupPal[lab][2]; end; end; modeBlur: begin if not AdjustSelected.Checked then begin ScrollBar.Max := 127; ScrollBar.LargeChange := 15; end else begin ScrollBar.Max := (selB - selA) div 2; ScrollBar.LargeChange := 2; end; Palette := Blur(ScrollBar.Position, BackupPal, na, nb); end; modeFrequency: if not AdjustSelected.Checked then Palette := Frequency(ScrollBar.Position, BackupPal) else Palette := FrequencySel(ScrollBar.Position, BackupPal); modeRed: // AV for i := na to nb do begin Palette[i][0] := BackupPal[i][0] + ScrollBar.Position; if Palette[i][0] > 255 then Palette[i][0] := 255; if Palette[i][0] < 0 then Palette[i][0] := 0; end; modeGreen: // AV for i := na to nb do begin Palette[i][1] := BackupPal[i][1] + ScrollBar.Position; if Palette[i][1] > 255 then Palette[i][1] := 255; if Palette[i][1] < 0 then Palette[i][1] := 0; end; modeBlue: // AV for i := na to nb do begin Palette[i][2] := BackupPal[i][2] + ScrollBar.Position; if Palette[i][2] > 255 then Palette[i][2] := 255; if Palette[i][2] < 0 then Palette[i][2] := 0; end; end; cp.cmap:=Palette; DrawPreview; end; procedure TAdjustForm.ScrollBarScroll(Sender: TObject; ScrollCode: TScrollCode; var ScrollPos: Integer); begin if ScrollCode = scEndScroll then begin GradientChanged:=false; Apply; end; end; { ***************************** Adjust menu ********************************* } procedure TAdjustForm.mnuRotateClick(Sender: TObject); begin btnMenu.Caption := TextByKey('adjustment-tab-gradient-moderotate'); scrollMode:=modeRotate; BackupPal := Palette; ScrollBar.Min := -128; ScrollBar.Max := 128; ScrollBar.LargeChange := 16; ScrollBar.Position := 0; end; procedure TAdjustForm.mnuHueClick(Sender: TObject); begin btnMenu.Caption := TextByKey('adjustment-tab-gradient-modehue'); scrollMode:=modeHue; BackupPal := Palette; ScrollBar.Min := -180; ScrollBar.Max := 180; ScrollBar.LargeChange := 15; ScrollBar.Position := 0; end; procedure TAdjustForm.mnuSaturationClick(Sender: TObject); begin btnMenu.Caption := TextByKey('adjustment-tab-gradient-modesaturation'); scrollMode:=modeSaturation; BackupPal := Palette; ScrollBar.Min := -100; ScrollBar.Max := 100; ScrollBar.LargeChange := 15; ScrollBar.Position := 0; end; procedure TAdjustForm.mnuLuminanceClick(Sender: TObject); begin btnMenu.Caption := TextByKey('adjustment-tab-gradient-modeluminance'); scrollMode := modeLuminance; BackupPal := Palette; ScrollBar.Min := -100; ScrollBar.Max := 100; ScrollBar.LargeChange := 15; ScrollBar.Position := 0; end; procedure TAdjustForm.mnuBrightnessClick(Sender: TObject); begin btnMenu.Caption := TextByKey('adjustment-tab-gradient-modebrightness'); scrollMode := modeBrightness; BackupPal := Palette; ScrollBar.Min := -255; ScrollBar.Max := 255; ScrollBar.LargeChange := 15; ScrollBar.Position := 0; end; procedure TAdjustForm.mnuContrastClick(Sender: TObject); begin btnMenu.Caption := TextByKey('adjustment-tab-gradient-modecontrast'); scrollMode := modeContrast; BackupPal := Palette; ScrollBar.Min := -100; ScrollBar.Max := 100; ScrollBar.LargeChange := 15; ScrollBar.Position := 0; end; procedure TAdjustForm.mnuBlurClick(Sender: TObject); begin btnMenu.Caption := TextByKey('adjustment-tab-gradient-modeblur'); scrollMode := modeBlur; BackupPal := Palette; ScrollBar.Min := 0; ScrollBar.Max := 127; ScrollBar.LargeChange := 15; ScrollBar.Position := 0; end; procedure TAdjustForm.mnuFrequencyClick(Sender: TObject); begin btnMenu.Caption := TextByKey('adjustment-tab-gradient-modefrequency'); scrollMode := modeFrequency; BackupPal := Palette; ScrollBar.Min := 1; ScrollBar.Max := 10; ScrollBar.LargeChange := 1; ScrollBar.Position := 1; end; // ----------------------------------------------------------------------------- procedure TAdjustForm.btnOpenClick(Sender: TObject); begin GradientBrowser.Filename := GradientFile; GradientBrowser.Show; end; procedure TAdjustForm.mnuSmoothPaletteClick(Sender: TObject); begin MainForm.SmoothPalette; end; procedure TAdjustForm.SaveGradient1Click(Sender: TObject); var gradstr: TStringList; begin gradstr := TStringList.Create; try SaveForm.SaveType := stSaveGradient; SaveForm.Filename := GradientFile; SaveForm.Title := MainCp.name; if SaveForm.ShowModal = mrOK then begin gradstr.add(CleanIdentifier(SaveForm.Title) + ' {'); gradstr.add(MainForm.GradientFromPalette(Palette, SaveForm.Title)); gradstr.add('}'); if MainForm.SaveGradient(gradstr.text, SaveForm.Title, SaveForm.Filename) then GradientFile := SaveForm.FileName; end; finally gradstr.free end; end; procedure TAdjustForm.SaveasMapfile1Click(Sender: TObject); begin SaveDialog.Filename := MainCp.name + '.map'; SaveDialog.Filter := Format('%s|*.map|%s|*.*', [ TextByKey('common-filter-fractintfiles'), TextByKey('common-filter-allfiles')]); if SaveDialog.execute then SaveMap(SaveDialog.Filename); end; procedure TAdjustForm.SaveAsScriptClick(Sender: TObject); var gradstr: TStringList; fn, s: string; i: word; begin SaveDialog.InitialDir := AppPath + 'Scripts'; SaveDialog.FileName := 'Palette_' + IntToStr(cmbPalette.ItemIndex) + '.asc'; SaveDialog.DefaultExt := 'asc'; SaveDialog.Filter := Format('%s|*.aposcript;*.asc|%s|*.*', [TextByKey('common-filter-scriptfiles'), TextByKey('common-filter-allfiles')]); if SaveDialog.Execute then begin fn := SaveDialog.FileName; gradstr := TStringList.Create; try gradstr.Add('procedure SetCustomPalette;'); gradstr.Add('begin'); gradstr.Add(' with Flame do begin'); for i := 0 to 255 do gradstr.Add(Format(' Gradient[%d,0] := %d; Gradient[%0:d,1] := %2:d; Gradient[%0:d,2] := %3:d;', [i, Palette[i][0], palette[i][1], palette[i][2]])); gradstr.Add(' end;'); gradstr.Add('end;'); s := ExtractFileName(fn); for i := 1 to Length(s) do if CharInSet(s[i], [#32, '-', '(', ')']) then s[i] := '_'; gradstr.SaveToFile(ExtractFilePath(fn) + s); MainForm.GetScripts; finally gradstr.Free; end; end; end; procedure TAdjustForm.cmbPaletteDrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState); var i, j: integer; Row: pRGBTripleArray; Bitmap: TBitmap; pal: TColorMap; PalName: string; begin { Draw the preset palettes on the combo box items } GetCMap(index, 1, pal); GetCmapName(index, PalName); BitMap := TBitMap.create; Bitmap.PixelFormat := pf24bit; BitMap.Width := 256; BitMap.Height := 100; for j := 0 to Bitmap.Height - 1 do begin Row := Bitmap.Scanline[j]; for i := 0 to Bitmap.Width - 1 do begin with Row[i] do begin rgbtRed := Pal[i][0]; rgbtGreen := Pal[i][1]; rgbtBlue := Pal[i][2]; end end end; with Control as TComboBox do begin Canvas.Rectangle(Rect); Canvas.TextOut(4, Rect.Top, PalName); Rect.Left := (Rect.Left + rect.Right) div 2; Canvas.StretchDraw(Rect, Bitmap); end; BitMap.Free; end; procedure TAdjustForm.btnCopyClick(Sender: TObject); var gradstr: TStringList; begin gradstr := TStringList.Create; try gradstr.add(CleanIdentifier(MainCp.name) + ' {'); gradstr.add('gradient:'); gradstr.add(' title="' + MainCp.name + '" smooth=no'); gradstr.add(GradientString(Palette)); gradstr.add('}'); Clipboard.SetTextBuf(PChar(gradstr.text)); btnPaste.enabled := true; mnuPaste.enabled := true; MainForm.mnuPaste.enabled := False; finally gradstr.free end; end; procedure TAdjustForm.btnPasteClick(Sender: TObject); begin //if Clipboard.HasFormat(CF_TEXT) then // AV: sometimes it isn't enough... if GradientInClipboard then // AV begin UpdateGradient(CreatePalette(Clipboard.AsText)); Apply; end else begin btnPaste.Enabled := False; // AV mnuPaste.Enabled := False; // AV end; end; function GradientInClipboard: boolean; var gradstr: TStringList; begin { returns true if gradient in clipboard - can be tricked } result := true; if Clipboard.HasFormat(CF_TEXT) then begin gradstr := TStringList.Create; try gradstr.text := ''; try gradstr.text := Clipboard.AsText; finally end; if (Pos('}', gradstr.text) = 0) or (Pos('{', gradstr.text) = 0) or (Pos('gradient:', gradstr.text) = 0) or (Pos('fractal:', gradstr.text) <> 0) then begin result := false; exit; end; finally gradstr.free; end; end else result := false; end; procedure TAdjustForm.AdjustColorFragmentClick(Sender: TObject); begin if ColorSelection.ShowModal = mrOK then begin GradStatusBar.Panels[2].Text := TextByKey('adjustment-tab-gradient-start') + space + IntToStr(selA); GradStatusBar.Panels[4].Text := TextByKey('adjustment-tab-gradient-last') + space + IntToStr(selB); GradStatusBar.Refresh; GradSelection.Refresh; AdjustSelected.Checked := True; //btnSelected.Visible := True; end; end; (* procedure TAdjustForm.ApplicationEventsActivate(Sender: TObject); begin if GradientInClipboard then begin mnuPaste.enabled := true; btnPaste.enabled := true; end else begin mnuPaste.enabled := false; btnPaste.enabled := false; end; end; *) procedure TAdjustForm.mnuSaveasDefaultClick(Sender: TObject); begin DefaultPalette := Palette; if not DirectoryExists(AppPath + 'Gradients\') then CreateDir(AppPath + 'Gradients\'); // AV SaveMap(AppPath + 'Gradients\default.map'); end; procedure TAdjustForm.mnuSepiaClick(Sender: TObject); var i, sep: smallint; begin for i := 0 to 255 do begin sep := Round(0.299 * Palette[i,0] + 0.587 * Palette[i,1] + 0.114 * Palette[i,2]); Palette[i,0] := IfThen(sep > 206, 255, sep + 49); Palette[i,1] := IfThen(sep < 14, 0, sep - 14); Palette[i,2] := IfThen(sep < 56, 0, sep - 56); end; UpdateGradient(palette); Apply; end; procedure TAdjustForm.mnuSetColorClick(Sender: TObject); var i: smallint; col: Longint; begin ColorDialog.Color := RGB(Palette[selA,0], Palette[selA,1], Palette[selA,2]); if ColorDialog.Execute then begin col := ColorToRGB(ColorDialog.Color); for i := selA to selB do begin Palette[i, 0] := col and 255; Palette[i, 1] := col shr 8 and 255; Palette[i, 2] := col shr 16 and 255; end; UpdateGradient(Palette); Apply; end; end; procedure TAdjustForm.mnuRandomizeClick(Sender: TObject); begin UpdateGradient(GradientHelper.RandomGradient); Apply; end; procedure TAdjustForm.GradientImageDblClick(Sender: TObject); begin mnuRandomizeClick(Sender); end; procedure TAdjustForm.GradientImageMouseLeave(Sender: TObject); begin GradStatusBar.Panels[0].Text := ''; GradStatusBar.Refresh; end; procedure TAdjustForm.GradImageMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if Button = mbLeft then begin dragX:=x; oldX:=x; // hmmm oldpos := (((x) shl 8) div GradientImage.Width) mod 256; if oldpos = 0 then oldpos := 1; startX := Round(x / (GradientImage.Width-1) * 255); // AV if startX < 0 then startX := 0 else if startX > 255 then startX := 255; tmpBackupPal := BackupPal; if ssCtrl in Shift then imgDragMode := imgDragStretch else if ssAlt in Shift then // AV imgDragMode := imgDragSelect else imgDragMode := imgDragRotate; GradientChanged:=false; end; end; procedure TAdjustForm.GradImageMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure StretchGradient(i0, i1, j0, j1: integer); var k, f: double; i, j, jj, n: integer; begin k := (j1 - j0) / (i1 - i0); if k >= 1 then begin for i := i0 to i1-1 do begin j := j0 + round((i - i0) * k); assert(j >= 0); assert(j < 256); cp.cmap[i] := Palette[j]; BackupPal[i] := tmpBackupPal[j]; //? end; end else begin for i := i0 to i1-1 do begin f := (i - i0) * k; j := j0 + trunc(f); f := frac(f); assert(j >= 0); assert(j < 256); if j < 255 then jj := j + 1 else jj := 0; for n := 0 to 2 do begin cp.cmap[i][n] := round( Palette[j][n]*(1-f) + Palette[jj][n]*f ); BackupPal[i][n] := round( tmpBackupPal[j][n]*(1-f) + tmpBackupPal[jj][n]*f ); //? end; end; end; end; var i, j, t: integer; k: double; begin t := Round(x / (GradientImage.Width-1) * 255) ; if (t < 0) then t := 0 else if (t > 255) then t := 255; GradStatusBar.Panels[0].Text := TextByKey('adjustment-tab-gradient-current') + space + IntToStr(t); GradStatusBar.Refresh; if (imgDragMode <> imgDragNone) and (oldX<>x) then begin oldX:=x; offset := (((x - dragX) shl 8) div GradientImage.Width) mod 256; txtVal.Text:=IntToStr(offset); txtVal.Refresh; //ScrollBar.Position := offset; GradientChanged := true; if imgDragmode = imgDragRotate then begin for i := 0 to 255 do begin cp.cmap[i] := Palette[(256 + i - offset) and $FF]; BackupPal[i] := tmpBackupPal[(256 + i - offset) and $FF]; end; end else if imgDragMode = imgDragSelect then begin selA := startX; selB := Round(x / (GradientImage.Width-1) * 255); if (selA > selB) then begin t := selA; selA := selB; selB := t; end; if (selA < 0) then selA := 0 else if (selA > 255) then selA := 255; if (selB < 0) then selB := 0 else if (selB > 255) then selB := 255; if (selB - selA > 1) then begin //btnSelected.Visible := True; AdjustSelected.Checked := True; end; GradStatusBar.Panels[2].Text := TextByKey('adjustment-tab-gradient-start') + space + IntToStr(selA); GradStatusBar.Panels[4].Text := TextByKey('adjustment-tab-gradient-last') + space + IntToStr(selB); GradStatusBar.Refresh; GradSelection.Refresh; end else begin offset := ((x shl 8) div GradientImage.Width); if offset <= 0 then offset := 1 else if offset > 255 then offset := 255; StretchGradient(0, offset, 0, oldpos); StretchGradient(offset, 256, oldpos, 256); end; DrawPreview; end; end; procedure TAdjustForm.GradImageMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if imgDragMode <> imgDragNone then begin imgDragMode := imgDragNone; txtVal.Text := '0'; Palette := cp.cmap; if GradientChanged then Apply; end; end; procedure TAdjustForm.GradSelectionPaint(Sender: TObject); var w: double; begin w := GradSelection.Width / 255; GradSelection.Canvas.Brush.Color := BrightColor; GradSelection.Canvas.FillRect(Rect(Round(w * selA), 0, Round(w * selB), 7)); end; procedure TAdjustForm.GradStatusBarDblClick(Sender: TObject); begin // AV: resetting color selection AdjustSelected.Checked := False; GradStatusBar.Panels[2].Text := ''; GradStatusBar.Panels[4].Text := ''; GradStatusBar.Refresh; //btnSelected.Visible := False; selA := 0; selB := 255; GradSelection.Refresh; end; procedure TAdjustForm.GradStatusBarDrawPanel(StatusBar: TStatusBar; Panel: TStatusPanel; const Rect: TRect); var i, n: integer; s: string; begin n := Panel.Index; if Odd(n) then if (StatusBar.Panels[n-1].Text <> '') then begin s := StatusBar.Panels[n-1].Text; n := pos(space, s); s := copy(s, n + 4, length(s) - n + 1); i := StrToInt(s); i := RGB(palette[i, 0], palette[i, 1], palette[i, 2]); StatusBar.Canvas.Brush.Color := i; StatusBar.Canvas.FillRect(Rect); end; end; //*************** AV: operations with selected color fragments **********// procedure TAdjustForm.InvertColorsClick(Sender: TObject); var i: integer; begin for i := selA to selB do begin Palette[i][0] := 255 - Palette[i][0]; Palette[i][1] := 255 - Palette[i][1]; Palette[i][2] := 255 - Palette[i][2]; end; UpdateGradient(palette); Apply; end; procedure TAdjustForm.LerpHSVClick(Sender: TObject); begin cmap.HSVBlend(selA, selB, palette); UpdateGradient(palette); Apply; end; procedure TAdjustForm.LerpRGBClick(Sender: TObject); begin cmap.RGBBlend(selA, selB, palette); UpdateGradient(palette); Apply; end; procedure TAdjustForm.MixcolorsClick(Sender: TObject); var i, j, l: integer; begin l := High(tmpColors); l := Min(selA + l, selB); for i := selA to l do for j := 0 to 2 do Palette[i][j] := Round((Palette[i][j] + tmpColors[i - selA][j])/2); UpdateGradient(palette); Apply; end; procedure TAdjustForm.Pastefragment1Click(Sender: TObject); var i, j, l: smallint; begin l := High(tmpColors); l := Min(selA + l, selB); for i := selA to l do for j := 0 to 2 do Palette[i][j] := tmpColors[i - selA][j]; UpdateGradient(palette); Apply; end; procedure TAdjustForm.ReverseFragmentClick(Sender: TObject); var i, j: byte; pal: array of array of byte; begin SetLength(pal, selB - selA + 1, 3); for i := selA to selB do for j := 0 to 2 do pal[i - selA][j] := Palette[i][j]; for i := 0 to selB - selA do for j := 0 to 2 do Palette[selB - i][j] := Pal[i][j]; UpdateGradient(palette); Apply; end; // --Z-- // image size functions ----------------------------------------------- function TAdjustForm.PresetToStr(n: integer): string; begin Result := IntToStr(Preset[n].Width) + ' x ' + IntToStr(Preset[n].Height) end; procedure TAdjustForm.RandomizeSelectedClick(Sender: TObject); var i, j: byte; tempPal: TColorMap; begin tempPal := GradientHelper.RandomGradient; for i := selA to selB do for j := 0 to 2 do Palette[i, j] := tempPal[i, j]; UpdateGradient(palette); Apply; end; procedure TAdjustForm.ReadPreset(n: integer); begin ImageWidth := Preset[n].Width; ImageHeight := Preset[n].Height; txtWidth.Text := IntToStr(ImageWidth); txtHeight.Text := IntToStr(ImageHeight); if chkResizeMain.Checked then begin MainForm.Left := Preset[n].Left; MainForm.Top := Preset[n].Top; end; SetMainWindowSize; end; procedure TAdjustForm.WeightChange(Sender: TObject); begin CurvesControl.WeightLeft := tbWeightLeft.Position / 10.0; CurvesControl.WeightRight := tbWeightRight.Position / 10.0; cp.curveWeights[cbChannel.ItemIndex][1] := tbWeightLeft.Position / 10.0; cp.curveWeights[cbChannel.ItemIndex][2] := tbWeightRight.Position / 10.0; DrawPreview; end; procedure TAdjustForm.WeightScroll(Sender: TObject; ScrollCode: TScrollCode; var ScrollPos: Integer); begin if ScrollCode <> scEndScroll then Exit; MainForm.StopThread; MainForm.UpdateUndo; MainCp.Copy(cp, true); if EditForm.Visible then EditForm.UpdateDisplay; if MutateForm.Visible then MutateForm.UpdateDisplay; MainForm.RedrawTimer.enabled := true; { if ScrollCode = scEndScroll then CurvesControl.UpdateFlame; } end; procedure TAdjustForm.WritePreset(n: integer); var Registry: TRegistry; w,h: integer; begin // Write preset to registry Registry := TRegistry.Create; try w:=StrToInt(txtWidth.text); h:=StrToInt(txtHeight.text); if (w>0) and (h>0) then begin Preset[n].Left:=MainForm.Left; Preset[n].Top:=MainForm.Top; Preset[n].Width:=w; Preset[n].Height:=h; end else exit; Registry.RootKey := HKEY_CURRENT_USER; if Registry.OpenKey('\Software\' + APP_NAME + '\ImageSizePresets', True) then begin Registry.WriteInteger('Preset'+IntToStr(n)+'Left', Preset[n].Left); Registry.WriteInteger('Preset'+IntToStr(n)+'Top', Preset[n].Top); Registry.WriteInteger('Preset'+IntToStr(n)+'Width', Preset[n].Width); Registry.WriteInteger('Preset'+IntToStr(n)+'Height', Preset[n].Height); end; except end; end; function IsNumeric(s: string): boolean; var i: integer; start:integer; begin Result := True; s := trim(s); if Length(s) = 0 then begin result := false; exit; end; start := 1; if (s[1] = '-') then start := 2; for i := start to length(s) do if not (CharInSet(s[i],['0'..'9'])) then begin Result := False; exit; end; end; procedure TAdjustForm.txtValExit(Sender: TObject); begin if (not IsNumeric(txtVal.Text)) then begin { It's not, so we restore the old value } txtVal.Text := IntToStr(ScrollBar.Position); exit; end; ScrollBar.Position := StrToInt(Trim(txtVal.Text)); txtVal.Text := Trim(txtVal.Text); UpdateFlame; end; procedure TAdjustForm.txtSizeKeyPress(Sender: TObject; var Key: Char); begin if key = #13 then begin key := #0; SetMainWindowSize; end; end; procedure TAdjustForm.cbAspectRatioChange(Sender: TObject); begin case cbAspectRatio.ItemIndex of 1: Ratio := ImageWidth / ImageHeight; 2: Ratio := 1.5; 3: Ratio := 4 / 3; 4: Ratio := 1.25; 5: Ratio := 16 / 9; 6: Ratio := 1.6; 7: Ratio := 21 / 9; end; end; { procedure TAdjustForm.chkMaintainClick(Sender: TObject); begin Ratio := ImageWidth / ImageHeight; end; } procedure TAdjustForm.SetMainWindowSize; var l, t, w, h: integer; begin MainCp.AdjustScale(ImageWidth, ImageHeight); MainForm.ResizeImage; //? if chkResizeMain.Checked then begin l := MainForm.Left; t := MainForm.Top; w := ImageWidth + MainForm.Width - (MainForm.BackPanel.Width - 2); h := ImageHeight + MainForm.Height - (MainForm.BackPanel.Height - 2); if w > Screen.Width then begin l := 0; w := Screen.width; end; if h > Screen.height then begin t := 0; h := Screen.height; end; MainForm.SetBounds(l, t, w, h); end; MainForm.RedrawTimer.Enabled := true; end; procedure TAdjustForm.GetMainWindowSize; begin ImageWidth := MainCP.Width; ImageHeight := MainCP.Height; txtWidth.text := IntToStr(ImageWidth); txtHeight.text := IntToStr(ImageHeight); end; procedure TAdjustForm.btnSelectedClick(Sender: TObject); begin SelectedPopup.Popup(btnSelected.ClientOrigin.x, btnSelected.ClientOrigin.y + btnSelected.Height); end; procedure TAdjustForm.btnSelectedMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if Button = mbRight then AdjustColorFragmentClick(Sender); end; procedure TAdjustForm.btnSet1Click(Sender: TObject); begin WritePreset(1); btnPreset1.Caption := PresetToStr(1); SetMainWindowSize; end; procedure TAdjustForm.btnSet2Click(Sender: TObject); begin WritePreset(2); btnPreset2.Caption := PresetToStr(2); SetMainWindowSize; end; procedure TAdjustForm.btnSet3Click(Sender: TObject); begin WritePreset(3); btnPreset3.Caption := PresetToStr(3); SetMainWindowSize; end; procedure TAdjustForm.btnPreset1Click(Sender: TObject); begin ReadPreset(1); end; procedure TAdjustForm.btnPreset2Click(Sender: TObject); begin ReadPreset(2); end; procedure TAdjustForm.btnPreset3Click(Sender: TObject); begin ReadPreset(3); end; procedure TAdjustForm.txtWidthChange(Sender: TObject); begin try ImageWidth := StrToInt(txtWidth.Text); if (cbAspectRatio.ItemIndex > 0) and txtWidth.Focused then begin ImageHeight := Round(ImageWidth / ratio); txtHeight.Text := IntToStr(ImageHeight) end; except end; end; procedure TAdjustForm.txtHeightChange(Sender: TObject); begin try ImageHeight := StrToInt(txtHeight.Text); if (cbAspectRatio.ItemIndex > 0) and txtHeight.Focused then begin ImageWidth := Round(ImageHeight * ratio); txtWidth.Text := IntToStr(ImageWidth) end; except end; end; procedure TAdjustForm.btnUndoClick(Sender: TObject); begin MainForm.Undo; end; procedure TAdjustForm.btResetZoomClick(Sender: TObject); var v: double; begin if cp.zoom = 0 then exit; // prevent useless updates v := cp.pixels_per_unit * power(2, cp.zoom); cp.pixels_per_unit := v; editPPU.Text := Format('%.6g', [100 * v / PreviewImage.Width]); cp.zoom := 0; txtZoom.Text := '0'; scrollZoom.Position := 0; UpdateFlame; end; procedure TAdjustForm.btnRedoClick(Sender: TObject); begin MainForm.Redo; end; procedure TAdjustForm.btnColorPresetClick(Sender: TObject); begin cmbPalette.ItemIndex := Random(NRCMAPS); cmbPaletteChange(Sender); end; procedure TAdjustForm.btnApplySizeClick(Sender: TObject); begin SetMainWindowSize; end; procedure TAdjustForm.mnuInstantPreviewClick(Sender: TObject); begin mnuInstantPreview.Checked := not mnuInstantPreview.Checked; end; procedure TAdjustForm.editPPUKeyPress(Sender: TObject; var Key: Char); begin if (Key = ',') then Key := '.'; if not CharinSet(Key,['0'..'9', #8, #13, '.']) then Key:= #0; if key=#13 then begin key := #0; editPPUValidate(Sender); end; end; procedure TAdjustForm.editPPUValidate(Sender: TObject); var v: double; begin try v := strtofloat(editPPU.Text); except exit; end; v := v/100*PreviewImage.Width; if (v > 0) and (cp.pixels_per_unit <> v) then begin MainForm.UpdateUndo; cp.pixels_per_unit := v; UpdateFlame; end; end; // ----------------------------------------------------------------------------- procedure TAdjustForm.DragPanelMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var enableDrag : boolean ; begin if Button <> mbLeft then exit; enableDrag := true; if (Sender = pnlMasterScale) then pnlDragValue := cp.pixels_per_unit / PreviewImage.Width else if (Sender = pnlZoom) then pnlDragValue := cp.zoom else if (Sender = pnlXpos) then pnlDragValue := cp.Center[0] else if (Sender = pnlYpos) then pnlDragValue := cp.Center[1] else if (Sender = pnlAngle) then pnlDragValue := cp.FAngle else if (Sender = pnlGamma) then pnlDragValue := cp.gamma else if (Sender = pnlBrightness) then pnlDragValue := cp.brightness else if (Sender = pnlVibrancy) then pnlDragValue := cp.vibrancy // 3d camera controls else if (Sender = pnlPitch) then pnlDragValue := cp.cameraPitch * 180.0 / PI else if (Sender = pnlYaw) then pnlDragValue := cp.cameraYaw * 180.0 / PI else if (Sender = pnlRoll) then // AV pnlDragValue := cp.cameraRoll * 180.0 / PI else if (Sender = pnlPersp) then pnlDragValue := cp.cameraPersp else if (Sender = pnlZpos) then pnlDragValue := cp.cameraZpos else if (Sender = pnlDOF) then pnlDragValue := cp.cameraDOF else if (Sender = pnlGammaThreshold) then pnlDragValue := cp.gammaThreshRelative else if (Sender = pnlContrast) then // AV pnlDragValue := cp.contrast // AV else enableDrag := false; //assert(false)}; if enableDrag then begin pnlDragMode := true; pnlDragPos := 0; pnlDragOld := x; pnlMM := false; //SetCaptureControl(TControl(Sender)); Screen.Cursor := crHSplit; //GetCursorPos(mousepos); // hmmm mousePos := (Sender as TControl).ClientToScreen(Point(x, y)); pnlDragged := false; end; end; procedure TAdjustForm.DragPanelMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var sc, v: double; begin if pnlMM then // hack: to skip MouseMove event begin pnlMM:=false; end else if pnlDragMode and (x <> pnlDragOld) then begin Inc(pnlDragPos, x - pnlDragOld); if GetKeyState(VK_MENU) < 0 then sc := 100000 else if GetKeyState(VK_CONTROL) < 0 then sc := 10000 else if GetKeyState(VK_SHIFT) < 0 then sc := 100 else sc := 1000; if (Sender = pnlPitch) or (Sender = pnlYaw) or (Sender = pnlRoll) then sc := sc / 50 else if Sender = pnlPersp then sc := sc * 10; v := Round6(pnlDragValue + pnlDragPos / sc); SetCursorPos(MousePos.x, MousePos.y); // hmmm pnlMM:=true; if (Sender = pnlMasterScale) then begin v := Round6(pnlDragValue * power(2, pnlDragPos / sc / 2)); if v <= 0.0001 then v := 0.0001; cp.pixels_per_unit := v*PreviewImage.Width; editPPU.Text := FloatToStr(v*100); end else if (Sender = pnlZoom) then begin scrollZoom.Position := trunc(v * 1000); end else if (Sender = pnlXpos) then begin scrollCenterX.Position := trunc(v * 1000); end else if (Sender = pnlYpos) then begin scrollCenterY.Position := trunc(v * 1000); end else if (Sender = pnlAngle) then begin scrollAngle.Position := Trunc(v * 18000.0 / PI) mod 36000; end else if (Sender = pnlGamma) then begin scrollGamma.Position := trunc(v * 100); end else if (Sender = pnlBrightness) then begin scrollBrightness.Position := trunc(v * 100); end else if (Sender = pnlVibrancy) then begin scrollVibrancy.Position := trunc(v * 100); end else if (Sender = pnlContrast) then // AV begin scrollContrast.Position := trunc(v * 100); end else if (Sender = pnlPitch) then // 3d camera controls begin v := v - 360*Trunc(v/360); cp.cameraPitch := v * PI / 180.0; txtPitch.Text := FloatToStr(v); end else if (Sender = pnlYaw) then begin v := v - 360*Trunc(v/360); cp.cameraYaw := v * PI / 180.0; txtYaw.Text := FloatToStr(v); end else if (Sender = pnlRoll) then // AV begin v := v - 360*Trunc(v/360); cp.cameraRoll := v * PI / 180.0; txtRoll.Text := FloatToStr(v); end else if (Sender = pnlPersp) then begin cp.cameraPersp := v; txtPersp.Text := FloatToStr(v); end else if (Sender = pnlZpos) then begin cp.cameraZpos := v; txtZpos.Text := FloatToStr(v); end else if (Sender = pnlDOF) then begin if v < 0 then v := 0; cp.cameraDOF := v; txtDOF.Text := FloatToStr(v); end else if (Sender = pnlGammaThreshold) then begin if v < 0 then v := 0; cp.gammaThreshRelative := v; txtGammaThreshold.Text := FloattoStr(cp.gammaThreshRelative); end else exit; //pEdit^.Text := FloatToStr(v); //pEdit.Refresh; pnlDragged := True; DrawPreview; end; end; procedure TAdjustForm.DragPanelMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if Button <> mbLeft then exit; if pnlDragMode then begin //SetCaptureControl(nil); pnlDragMode := false; Screen.Cursor := crDefault; if pnlDragged then begin UpdateFlame; pnlDragged := False; end; end; end; procedure TAdjustForm.DarkRemoverClick(Sender: TObject); const level = 45; var isDark: boolean; i, r, g, b: byte; begin isDark := False; for i := 0 to 255 do begin r := Palette[i,0]; g := Palette[i,1]; b := Palette[i,2]; if (r < level) and (g < level) and (b < level) then begin isDark := True; Brighten(level, r, g, b); Palette[i,0] := r; Palette[i,1] := g; Palette[i,2] := b; end; end; if isDark then begin UpdateGradient(palette); Apply; end; end; procedure TAdjustForm.DragPanelDblClick(Sender: TObject); var pValue: ^double; begin if (Sender = pnlMasterScale) then begin pValue := @cp.pixels_per_unit; if pValue^ = PreviewImage.Width/4 then exit; pValue^ := PreviewImage.Width/4; editPPU.Text := FloatToStr(100*pValue^/PreviewImage.Width); end else if (Sender = pnlZoom) then begin scrollZoom.Position := 0; txtZoom.Text := '0'; // AV end else if (Sender = pnlXpos) then begin scrollCenterX.Position := 0; txtCenterX.Text := '0'; // AV end else if (Sender = pnlYpos) then begin scrollCenterY.Position := 0; txtCenterY.Text := '0'; // AV end else if (Sender = pnlAngle) then begin scrollAngle.Position := 0; txtAngle.Text := '0'; // AV end else if (Sender = pnlGamma) then begin scrollGamma.Position := Round(defGamma * 100); txtGamma.Text := FloatToStr(defGamma); // AV end else if (Sender = pnlBrightness) then begin scrollBrightness.Position := Round(defBrightness * 100); txtBrightness.Text := FloatToStr(defBrightness); // AV end else if (Sender = pnlVibrancy) then begin scrollVibrancy.Position := Round(defVibrancy * 100); txtVibrancy.Text := FloatToStr(defVibrancy); // AV end else if (Sender = pnlContrast) then // AV begin scrollContrast.Position := Round(defContrast * 100); // AV txtContrast.Text := FloatToStr(defContrast); // AV end // 3d camera controls else if (Sender = pnlPitch) then begin cp.cameraPitch := 0; txtPitch.Text := '0'; end else if (Sender = pnlYaw) then begin cp.cameraYaw := 0; txtYaw.Text := '0'; end else if (Sender = pnlRoll) then // AV begin cp.cameraRoll := 0; txtRoll.Text := '0'; end else if (Sender = pnlPersp) then begin if cp.cameraPersp = 0 then cp.cameraPersp := 0.125 else cp.cameraPersp := 0; txtPersp.Text := FloatToStr(cp.cameraPersp); end else if (Sender = pnlZpos) then begin cp.cameraZpos := 0; txtZpos.Text := '0'; end else if (Sender = pnlDOF) then begin cp.cameraDOF := 0; txtDOF.Text := '0'; end else if (Sender = pnlGammaThreshold) then begin // AV: commented out to reset user's input text properly // if cp.gammaThreshRelative = defGammaThreshold then exit; cp.gammaThreshRelative := defGammaThreshold; txtGammaThreshold.Text := FloatToStr(defGammaThreshold); end else exit; //assert(false); UpdateFlame; end; procedure TAdjustForm.Fliplefthalf1Click(Sender: TObject); var i: byte; begin for i := 0 to 127 do begin Palette[255-i,0] := Palette[i,0]; Palette[255-i,1] := Palette[i,1]; Palette[255-i,2] := Palette[i,2]; end; UpdateGradient(palette); Apply; end; procedure TAdjustForm.Fliprighthalf1Click(Sender: TObject); var i: byte; begin for i := 0 to 127 do begin Palette[i,0] := Palette[255-i,0]; Palette[i,1] := Palette[255-i,1]; Palette[i,2] := Palette[255-i,2]; end; UpdateGradient(palette); Apply; end; procedure TAdjustForm.FormActivate(Sender: TObject); begin txtVibrancy.text := FloatToStr(cp.Vibrancy); txtGamma.text := FloatToStr(cp.Gamma); txtBrightness.text := FloatToStr(cp.Brightness); txtContrast.text := FloatToStr(cp.Contrast); // AV txtGammaThreshold.text := FloatToStr(cp.gammaThreshRelative); // AV txtZoom.text := FloatToStr(cp.zoom); txtCenterX.text := FloatToStr(cp.center[0]); txtCentery.text := FloatToStr(cp.center[1]); txtAngle.text := FloatToStr(cp.FAngle * 180 / PI); btnPaste.Enabled := GradientInClipboard; // AV mnuPaste.Enabled := btnPaste.Enabled; // AV end; /////////////////////////////////////////////////////////////////////////////// procedure TAdjustForm.txtCamEnter(Sender: TObject); begin EditBoxValue := (Sender as TEdit).Text; end; procedure TAdjustForm.txtCamPitchExit(Sender: TObject); var v: double; begin if (EditBoxValue <> txtPitch.Text) then try v := StrToFloat(txtPitch.Text); v := v - 360*Trunc(v/360); txtPitch.Text := FloatToStr(v); cp.cameraPitch := v * PI / 180; UpdateFlame; except on EConvertError do txtPitch.Text := FloatToStr(cp.cameraPitch / PI * 180); end; end; procedure TAdjustForm.txtCamPitchKeyPress(Sender: TObject; var Key: Char); begin if (Key = ',') then Key := '.'; if not CharinSet(Key,['0'..'9','-', #8, #13, '.']) then Key:= #0; if ((key = #13) and (EditBoxValue <> (Sender as TEdit).Text)) then begin key := #0; txtCamPitchExit(Sender); end; end; procedure TAdjustForm.txtCamRollExit(Sender: TObject); var v: double; begin if (EditBoxValue <> txtRoll.Text) then try v := StrToFloat(txtRoll.Text); v := v - 360*Trunc(v/360); txtRoll.Text := FloatToStr(v); cp.cameraRoll := v * PI / 180; UpdateFlame; except on EConvertError do txtRoll.Text := FloatToStr(cp.cameraRoll / PI * 180); end; end; procedure TAdjustForm.txtCamRollKeyPress(Sender: TObject; var Key: Char); begin if (Key = ',') then Key := '.'; if not CharinSet(Key,['0'..'9','-', #8, #13, '.']) then Key:= #0; if ((key = #13) and (EditBoxValue <> (Sender as TEdit).Text)) then begin key := #0; txtCamRollExit(Sender); end; end; procedure TAdjustForm.txtCamYawExit(Sender: TObject); var v: double; begin if (EditBoxValue <> txtYaw.Text) then try v := StrToFloat(txtYaw.Text); v := v - 360*Trunc(v/360); txtYaw.Text := FloatToStr(v); cp.cameraYaw := v * PI / 180; UpdateFlame; except on EConvertError do txtYaw.Text := FloatToStr(cp.cameraYaw / PI * 180); end; end; procedure TAdjustForm.txtCamYawKeyPress(Sender: TObject; var Key: Char); begin if (Key = ',') then Key := '.'; if not CharinSet(Key,['0'..'9','-', #8, #13, '.']) then Key:= #0; if ((key = #13) and (EditBoxValue <> (Sender as TEdit).Text)) then begin key := #0; txtCamYawExit(Sender); end; end; procedure TAdjustForm.txtCamDistExit(Sender: TObject); begin if (EditBoxValue <> txtPersp.Text) then try cp.cameraPersp := StrToFloat(txtPersp.Text); UpdateFlame; except on EConvertError do txtPersp.Text := FloatToStr(cp.cameraPersp); end; end; procedure TAdjustForm.txtCamDistKeyPress(Sender: TObject; var Key: Char); begin if (Key = ',') then Key := '.'; if not CharinSet(Key,['0'..'9','-', #8, #13, '.']) then Key:= #0; // AV if ((key = #13) and (EditBoxValue <> (Sender as TEdit).Text)) then begin key := #0; txtCamDistExit(Sender); end; end; procedure TAdjustForm.txtCamZposExit(Sender: TObject); begin if (EditBoxValue <> txtZpos.Text) then try cp.cameraZpos := StrToFloat(txtZpos.Text); txtZpos.Text := FloatToStr(cp.cameraZpos); UpdateFlame; except on EConvertError do txtZpos.Text := FloatToStr(cp.cameraZpos); end; end; procedure TAdjustForm.txtCamZposKeyPress(Sender: TObject; var Key: Char); begin if (Key = ',') then Key := '.'; if not CharinSet(Key,['0'..'9','-', #8, #13, '.']) then Key:= #0; // AV if ((key = #13) and (EditBoxValue <> (Sender as TEdit).Text)) then begin key := #0; txtCamZposExit(Sender); end; end; procedure TAdjustForm.txtCamDofExit(Sender: TObject); begin if (EditBoxValue <> txtDof.Text) then try cp.cameraDOF := StrToFloat(txtDof.Text); txtDof.Text := FloatToStr(cp.cameraDOF); UpdateFlame; except on EConvertError do txtDof.Text := FloatToStr(cp.cameraDOF); end; end; procedure TAdjustForm.txtCamDofKeyPress(Sender: TObject; var Key: Char); begin if (Key = ',') then Key := '.'; if not CharinSet(Key,['0'..'9','-', #8, #13, '.']) then Key:= #0; if ((key = #13) and (EditBoxValue <> (Sender as TEdit).Text)) then begin key := #0; txtCamDofExit(Sender); end; end; procedure TAdjustForm.PreviewImageMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if Button <> mbLeft then exit; camDragValueY := cp.cameraPitch * 180.0 / PI; camDragValueX := cp.cameraYaw * 180.0 / PI; camDragMode := true; camDragPos.x := 0; camDragPos.y := 0; camDragOld.x := x; camDragOld.y := y; camMM := false; //SetCaptureControl(TControl(Sender)); Screen.Cursor := crNone; //GetCursorPos(mousepos); // hmmm mousePos := (Sender as TControl).ClientToScreen(Point(x, y)); camDragged := false; end; procedure TAdjustForm.PreviewImageMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var sc, vx, vy: double; begin if camMM then // hack: to skip MouseMove event begin camMM:=false; end else if camDragMode and ( (x <> camDragOld.x) or (y <> camDragOld.y) ) then begin Inc(camDragPos.x, x - camDragOld.x); Inc(camDragPos.y, y - camDragOld.y); vx := Round6(camDragValueX + camDragPos.x / 10); vy := Round6(camDragValueY - camDragPos.y / 10); cp.cameraPitch := vy * PI / 180.0; txtPitch.Text := FloatToStr(vy); txtPitch.Refresh; cp.cameraYaw := vx * PI / 180.0; txtYaw.Text := FloatToStr(vx); txtYaw.Refresh; SetCursorPos(MousePos.x, MousePos.y); // hmmm pnlMM:=true; camDragged := True; DrawPreview; end; end; procedure TAdjustForm.PreviewImageMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if Button <> mbLeft then exit; if camDragMode then begin camDragMode := false; Screen.Cursor := crDefault; if camDragged then begin UpdateFlame; camDragged := False; end; end; end; procedure TAdjustForm.PreviewImageDblClick(Sender: TObject); begin cp.cameraPitch := 0; txtPitch.Text := '0'; cp.cameraYaw := 0; txtYaw.Text := '0'; cp.cameraRoll := 0; // AV txtRoll.Text := '0'; cp.cameraZpos := 0; // AV txtZpos.Text := '0'; cp.cameraPersp := 0; // AV txtPersp.Text := '0'; cp.cameraDOF := 0; // AV txtDOF.Text := '0'; scrollCenterX.Position := 0; scrollCenterY.Position := 0; UpdateFlame; end; procedure TAdjustForm.txtGammaThresholdEnter(Sender: TObject); begin EditBoxValue := txtGammaThreshold.Text; end; procedure TAdjustForm.txtGammaThresholdExit(Sender: TObject); var v: double; begin try v := strtofloat(txtGammaThreshold.Text); except exit; end; if v < 0 then v := 0; if v <> cp.gammaThreshRelative then begin MainForm.UpdateUndo; cp.gammaThreshRelative := v; txtGammaThreshold.Text := FloatToStr(cp.gammaThreshRelative); UpdateFlame; EditBoxValue := txtGammaThreshold.Text; end; end; procedure TAdjustForm.txtGammaThresholdKeyPress(Sender: TObject; var Key: Char); begin if (Key = ',') then Key := '.'; if not CharinSet(Key,['0'..'9', #8, #13, '.']) then Key:= #0; if key=#13 then begin key := #0; txtGammaThresholdExit(Sender); end; end; procedure TAdjustForm.Shape1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin ColorPanelClick(nil); end; procedure TAdjustForm.Smoothize1Click(Sender: TObject); begin MainForm.Smoothize(Palette, 0, 255); end; procedure TAdjustForm.SmoothizeSelectedClick(Sender: TObject); begin MainForm.Smoothize(Palette, selA, selB); end; procedure TAdjustForm.btnResetClick(Sender: TObject); begin ScrollBar.Position := 0; end; procedure TAdjustForm.btnResetCurvesClick(Sender: TObject); var i: integer; begin tbWeightLeft.Position := 10; tbWeightRight.Position := 10; with cp do for i := 0 to 3 do begin curvePoints[i][0].x := 0.00; curvePoints[i][0].y := 0.00; curveWeights[i][0] := 1; curvePoints[i][1].x := 0.00; curvePoints[i][1].y := 0.00; curveWeights[i][1] := 1; curvePoints[i][2].x := 1.00; curvePoints[i][2].y := 1.00; curveWeights[i][2] := 1; curvePoints[i][3].x := 1.00; curvePoints[i][3].y := 1.00; curveWeights[i][3] := 1; end; MainCp.Copy(cp, true); SetCurvesCp(MainCp); Apply; end; procedure TAdjustForm.txtValKeyPress(Sender: TObject; var Key: Char); begin if (Key = ',') then Key := '.'; if not CharinSet(Key,['0'..'9','-', #8, #13, '.']) then Key:= #0; if Key=#13 then begin Key := #0; txtValExit(sender); end; end; {procedure TAdjustForm.TemplateRandomizeGradient; begin mnuRandomizeClick(nil); end; } end.