📄 jvqfullcolorctrls.pas
字号:
end;
procedure TJvFullColorPanel.SetReverseAxisX(const Value: Boolean);
begin
if FReverseAxisX <> Value then
begin
FReverseAxisX := Value;
WantDrawBuffer := True;
end;
end;
procedure TJvFullColorPanel.SetReverseAxisY(const Value: Boolean);
begin
if FReverseAxisY <> Value then
begin
FReverseAxisY := Value;
WantDrawBuffer := True;
end;
end;
procedure TJvFullColorPanel.SetPen(const Value: TPen);
begin
FPen.Assign(Value);
Invalidate;
end;
procedure TJvFullColorPanel.SetColorTrackBar(const Value: TJvFullColorTrackBar);
begin
if (Value <> nil) and (Value <> FColorTrackBar) and Value.Linked then
raise EJvFullColorError.CreateResFmt(@Rs_EDuplicateTrackBar, [Value.LinkerName]);
if Assigned(FColorTrackBar) then
begin
FColorTrackBar.OnColorChange := nil;
FColorTrackBar.OnAxisConfigChange := nil;
FColorTrackBar.RemoveFreeNotification(Self);
FColorTrackBar.FreeLink;
end;
FColorTrackBar := Value;
if Assigned(FColorTrackBar) then
begin
FColorTrackBar.OnColorChange := TrackBarColorChange;
FColorTrackBar.OnAxisConfigChange := TrackBarAxisConfigChange;
FColorTrackBar.FullColor := FullColor;
FColorTrackBar.AxisConfig := AxisConfig;
FColorTrackBar.FreeNotification(Self);
FColorTrackBar.SetLink(Self);
end;
end;
procedure TJvFullColorPanel.Notification(AComponent: TComponent; Operation: TOperation);
begin
if (Operation = opRemove) and (AComponent = ColorTrackBar) then
ColorTrackBar := nil;
inherited Notification(AComponent, Operation);
end;
procedure TJvFullColorPanel.SetFullColor(const Value: TJvFullColor);
var
AxisX, AxisY: TJvAxisIndex;
begin
if Value <> FullColor then
begin
if Assigned(FColorTrackBar) and (not FColorChanging) then
begin
FColorChanging := True;
FColorTrackBar.FullColor := Value;
FColorChanging := False;
end;
begin
AxisX := GetIndexAxisX(AxisConfig);
AxisY := GetIndexAxisY(AxisConfig);
if (GetAxisValue(Value, AxisX) <> GetAxisValue(FullColor, AxisX)) or
(GetAxisValue(Value, AxisY) <> GetAxisValue(FullColor, AxisY)) then
begin
InvalidateCursor;
inherited SetFullColor(Value);
InvalidateCursor;
end
else
inherited SetFullColor(Value);
end;
end;
end;
procedure TJvFullColorPanel.MouseColor(Shift: TShiftState; X, Y: Integer);
var
MinX, MaxX, MinY, MaxY: Byte;
AxisX, AxisY: TJvAxisIndex;
PosX, PosY: Integer;
begin
if (ssLeft in Shift) then
begin
AxisX := GetIndexAxisX(AxisConfig);
AxisY := GetIndexAxisY(AxisConfig);
with ColorSpace do
begin
MinX := AxisMin[AxisX];
MaxX := AxisMax[AxisX];
MinY := AxisMin[AxisY];
MaxY := AxisMax[AxisY];
PosX := EnsureRange(((X - CrossSize) * (MaxX - MinX)) div (FBuffer.Width - 1), 0, MaxX - MinX);
if ReverseAxisX then
PosX := MaxX - PosX
else
PosX := PosX + MinX;
PosY := EnsureRange(((Y - CrossSize) * (MaxY - MinY)) div (FBuffer.Height - 1), 0, MaxY - MinY);
if ReverseAxisY then
PosY := MaxY - PosY
else
PosY := PosY + MinY;
FullColor := SetAxisValue(SetAxisValue(FullColor, AxisX, Byte(PosX)), AxisY, Byte(PosY));
end;
end;
inherited MouseColor(Shift, X, Y);
end;
procedure TJvFullColorPanel.AxisConfigChange;
begin
if (FColorTrackBar <> nil) and not FAxisConfigChanging then
begin
FAxisConfigChanging := True;
FColorTrackBar.AxisConfig := AxisConfig;
FAxisConfigChanging := False;
end;
inherited AxisConfigChange;
end;
procedure TJvFullColorPanel.KeyMove(KeyCode: TJvKeyCode; MoveCount: Integer);
var
IndexAxisX, IndexAxisY: TJvAxisIndex;
ValueX, ValueY: Integer;
begin
IndexAxisX := GetIndexAxisX(AxisConfig);
IndexAxisY := GetIndexAxisY(AxisConfig);
ValueX := GetAxisValue(FullColor, IndexAxisX);
ValueY := GetAxisValue(FullColor, IndexAxisY);
case KeyCode of
kcLeft:
begin
if ReverseAxisX then
MoveCount := -MoveCount;
ValueX := ValueX - MoveCount;
end;
kcRight:
begin
if ReverseAxisX then
MoveCount := -MoveCount;
ValueX := ValueX + MoveCount;
end;
kcUp:
begin
if ReverseAxisY then
MoveCount := -MoveCount;
ValueY := ValueY - MoveCount;
end;
kcDown:
begin
if ReverseAxisY then
MoveCount := -MoveCount;
ValueY := ValueY + MoveCount;
end;
end;
with ColorSpace do
begin
ValueX := EnsureRange(ValueX, AxisMin[IndexAxisX], AxisMax[IndexAxisX]);
ValueY := EnsureRange(ValueY, AxisMin[IndexAxisY], AxisMax[IndexAxisY]);
end;
FullColor := SetAxisValue(SetAxisValue(FullColor, IndexAxisX, ValueX), IndexAxisY, ValueY);
end;
//=== { TJvColorCircle } =====================================================
constructor TJvFullColorCircle.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FCrossStyle := TPen.Create;
FCrossStyle.OnChange := PenChanged;
FInvertRadius := False;
InvertRotation := False;
FCrossSize := 5;
FCrossCenter := 1;
FLineWidth := 1;
FRedColor := fclRGBRed;
FGreenColor := fclRGBLime;
FBlueColor := fclRGBBlue;
FDraggingColor := rcCommon;
FCrossGreenColor := clGreen;
FCrossRedColor := clMaroon;
FCrossBlueColor := clNavy;
FStyles := [csShowLines, csShowRed, csShowGreen, csShowBlue];
end;
destructor TJvFullColorCircle.Destroy;
begin
FCrossStyle.Free;
inherited Destroy;
end;
procedure TJvFullColorCircle.CalcSize;
begin
FBuffer.Width := Max(Width - (2 * CrossSize),0);
FBuffer.Height := Max(Height - (2 * CrossSize),0);
inherited CalcSize;
end;
procedure TJvFullColorCircle.DrawBuffer;
var
X, Y, Angle, RadiusInt, MaxRadius, MinRadius: Integer;
AxisRadius, AxisAngle: TJvAxisIndex;
MaxAngle, MinAngle: Integer;
AngleUnit, AngleUnitPi, XCenter, YCenter, XRelative, YRelative,
SqrXRelative, SqrYRelative, Radius: Extended;
Magic1, Magic2, Magic3: Byte;
Line: PJvFullColorArray;
begin
if (FBuffer.Width = 0) or (FBuffer.Height = 0) then
Exit;
AxisRadius := GetIndexAxisX(AxisConfig);
AxisAngle := GetIndexAxisY(AxisConfig);
with ColorSpace do
begin
MaxRadius := AxisMax[AxisRadius];
MinRadius := AxisMin[AxisRadius];
MaxAngle := AxisMax[AxisAngle];
MinAngle := AxisMin[AxisAngle];
end;
AngleUnit := (MaxAngle - MinAngle) / 2.0 / Pi;
AngleUnitPi := (MaxAngle - MinAngle) / 2.0;
Magic1 := ValueZ;
Magic2 := Magic1;
Magic3 := Magic1;
with FBuffer, ColorSpace do
begin
Canvas.Brush.Color := Color;
Canvas.FillRect(Rect(0, 0, Width, Height));
XCenter := Width / 2.0;
YCenter := Height / 2.0;
for Y := 0 to Height - 1 do
begin
Line := ScanLine[Y];
YRelative := Y - YCenter;
SqrYRelative := Sqr(YRelative / YCenter);
for X := 0 to Width - 1 do
begin
XRelative := X - XCenter;
SqrXRelative := Sqr(XRelative / XCenter);
Radius := Sqrt(SqrYRelative + SqrXRelative);
if Radius <= 1.0 then
begin
Angle := Round(ArcTan2(YRelative, XRelative) * AngleUnit + AngleUnitPi) + MinAngle;
RadiusInt := Round(Radius * (MaxRadius - MinRadius));
case AxisAngle of
axIndex0:
if InvertRotation then
Magic1 := MaxAngle - Angle
else
Magic1 := Angle + MinAngle;
axIndex1:
if InvertRotation then
Magic2 := MaxAngle - Angle
else
Magic2 := Angle + MinAngle;
axIndex2:
if InvertRotation then
Magic3 := MaxAngle - Angle
else
Magic3 := Angle + MinAngle;
end;
case AxisRadius of
axIndex0:
if InvertRadius then
Magic1 := MaxRadius - RadiusInt
else
Magic1 := RadiusInt + MinRadius;
axIndex1:
if InvertRadius then
Magic2 := MaxRadius - RadiusInt
else
Magic2 := RadiusInt + MinRadius;
axIndex2:
if InvertRadius then
Magic3 := MaxRadius - RadiusInt
else
Magic3 := RadiusInt + MinRadius;
end;
// (outchy) don't remove, Bitmap colors are stocked as (MSB) 00RRGGBB (LSB)
// Delphi TColor is (MSB) 00BBGGRR (LSB)
Line[X] := RGBToBGR(ConvertToColor(Magic1 or (Magic2 shl 8) or (Magic3 shl 16)));
end
else
if XRelative >= 0.0 then
Break; // end of a line
end;
end;
end;
inherited DrawBuffer;
end;
procedure TJvFullColorCircle.Paint;
procedure DrawCross(AFullColor: TJvFullColor; ACrossColor: TColor);
var
Point: TPoint;
begin
Point := FullColorToPosition(AFullColor);
with Canvas do
begin
Pen := CrossStyle;
Pen.Color := ACrossColor;
MoveTo(Point.X - CrossSize, Point.Y); // left
LineTo(Point.X - CrossCenter, Point.Y);
MoveTo(Point.X + CrossCenter, Point.Y); // right
LineTo(Point.X + CrossSize, Point.Y);
MoveTo(Point.X, Point.Y - CrossSize); // top
LineTo(Point.X, Point.Y - CrossCenter);
MoveTo(Point.X, Point.Y + CrossCenter); // bottom
LineTo(Point.X, Point.Y + CrossSize);
Pen.Mode := pmCopy;
Pen.Style := psSolid;
Pen.Width := LineWidth;
MoveTo((FBuffer.Width div 2) + CrossSize + 1,(FBuffer.Height div 2 ) + CrossSize + 1);
LineTo(Point.X, Point.Y);
end;
end;
begin
inherited Paint;
with Canvas do
begin
Brush.Color := Color;
DrawFrame(CrossSize, CrossSize);
Draw(CrossSize, CrossSize, FBuffer);
if csShowCommon in Styles then
DrawCross(FullColor, CrossStyle.Color)
else
begin
if csShowBlue in Styles then
DrawCross(BlueColor, CrossBlueColor);
if csShowRed in Styles then
DrawCross(RedColor, CrossRedColor);
if csShowGreen in Styles then
DrawCross(GreenColor, CrossGreenColor);
end;
end;
DrawFocus;
end;
function TJvFullColorCircle.FullColorToPosition(AFullColor: TJvFullColor): TPoint;
var
ColorID: TJvFullColorSpaceID;
RadiusIndex, AngleIndex: TJvAxisIndex;
Radius, RadiusMax, RadiusMin, Angle, AngleMax, AngleMin: Integer;
Radius1: Integer;
FullAngle: Extended;
begin
with ColorSpaceManager do
begin
ColorID := GetColorSpaceID(AFullColor);
if ColorID <> GetColorSpaceID(AFullColor) then
AFullColor := ConvertToID(AFullColor, ColorID);
end;
with ColorSpace do
begin
RadiusIndex := GetIndexAxisX(AxisConfig);
Radius := GetAxisValue(AFullColor, RadiusIndex);
RadiusMax := AxisMax[RadiusIndex];
RadiusMin := AxisMin[RadiusIndex];
AngleIndex := GetIndexAxisY(AxisConfig);
Angle := GetAxisValue(AFullColor, AngleIndex);
AngleMax := AxisMax[AngleIndex];
AngleMin := AxisMin[AngleIndex];
end;
Radius1 := RadiusMax - RadiusMin;
if InvertRadius then
Radius := RadiusMax - Radius
else
Radius := Radius - RadiusMin;
if InvertRotation then
Angle := AngleMax - Angle
else
Angle := Angle - AngleMin;
FullAngle := (2 * Pi * Angle) / (AngleMax - AngleMin) - Pi;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -