dxskinscore.pas
来自「胜天进销存源码,国产优秀的进销存」· PAS 代码 · 共 2,155 行 · 第 1/5 页
PAS
2,155 行
end;
Draw(ABitmap.Canvas.Handle, Rect(0, 0, Size.cx, Size.cy), AImageIndex, AState);
end;
procedure TdxSkinImage.LoadFromFile(const AFileName: string);
var
AFile : TFileStream;
begin
FSourceName := AFileName;
AFile := TFileStream.Create(AFileName, fmOpenRead or fmShareDenyNone);
try
Texture.LoadFromStream(AFile);
finally
AFile.Free;
end;
DoChange;
end;
procedure TdxSkinImage.SaveToFile(const AFileName: string);
begin
if Empty then Exit;
Texture.SaveToFile(ChangeFileExt(AFileName, '.png'));
DoChange;
end;
procedure TdxSkinImage.SetStateMapping(AStateOrder: array of TdxSkinElementState);
var
ASrc: TRect;
ASize: TSize;
ABitmap: TBitmap;
AIndex, AImageIndex: Integer;
begin
if Texture.Empty then Exit;
ABitmap := Texture.GetAsBitmap;
try
ASize := Size;
ASrc := Rect(0, 0, ASize.cx, ASize.cy);
if ImageLayout = ilHorizontal then
ASize.cy := 0
else
ASize.cx := 0;
for AImageIndex := 0 to ImageCount - 1 do
for AIndex := Low(AStateOrder) to High(AStateOrder) do
begin
if not (AStateOrder[AIndex] in States) then Continue;
Texture.StretchDraw(ABitmap.Canvas.Handle,
StateBounds[AImageIndex, AStateOrder[AIndex]], ASrc);
OffsetRect(ASrc, ASize.cx, ASize.cy);
end;
Texture.SetBitmap(ABitmap);
finally
ABitmap.Free;
end;
end;
procedure TdxSkinImage.CheckInfo;
begin
if not IsDirty then Exit;
IsDirty := False;
DoInitializeInfo;
end;
procedure TdxSkinImage.CheckState(var AState: TdxSkinElementState);
var
AFirstState: TdxSkinElementState;
begin
if not (AState in FStates) then
for AFirstState := Low(TdxSKinElementState) to High(TdxSKinElementState) do
if AFirstState in FStates then
begin
AState := AFirstState;
Break;
end;
end;
function TdxSkinImage.Compare(AImage: TdxSkinImage): Boolean;
begin
Result := (AImage.ImageLayout = ImageLayout) and (AImage.Empty = Empty) and
(AImage.States = States) and (AImage.Gradient = Gradient) and
(AImage.GradientBeginColor = GradientBeginColor) and
(AImage.GradientEndColor = GradientEndColor) and (AImage.Stretch = Stretch) and
(AImage.Size.cx = Size.cx) and (AImage.Size.cy = Size.cy) and
AImage.Margins.IsEqual(Margins.Rect) and Texture.Compare(AImage.Texture);
end;
procedure TdxSkinImage.Draw(DC: HDC; const ARect: TRect;
AImageIndex: Integer = 0; AState: TdxSkinElementState = esNormal);
var
ACanvas: TdxSkinCanvas;
begin
CheckInfo;
if (FSize.cx <= 0) or (FSize.cy <= 0) or IsRectEmpty(ARect) or not RectVisible(DC, ARect) then Exit;
ACanvas := TdxSkinCanvas.Create;
try
ACanvas.BeginPaint(DC, ARect);
DrawEx(ACanvas, ARect, AImageIndex, AState);
ACanvas.EndPaint;
finally
ACanvas.Free;
end;
end;
procedure TdxSkinImage.DrawEx(ACanvas: TdxSkinCanvas; const ARect: TRect;
AImageIndex: Integer = 0; AState: TdxSkinElementState = esNormal);
var
ACol, ARow: Integer;
AVisibility: TdxSkinElementPartVisibility;
DestParts, SourceParts: TdxSkinElementPartBounds;
begin
if Empty then Exit;
CheckInfo;
CheckState(AState);
if Stretch = smNoResize then
ACanvas.DrawImage(Texture, cxRectCenter(ARect, Size), StateBounds[AImageIndex, AState])
else
begin
FillChar(AVisibility, SizeOf(AVisibility), 1);
InitializePartsInfo(StateBounds[AImageIndex, AState], SourceParts, AVisibility, False);
InitializePartsInfo(ARect, DestParts, AVisibility, True);
for ARow := 0 to 2 do
for ACol := 0 to 2 do
if AVisibility[ACol, ARow] then
begin
DrawPart(ACanvas, DestParts[ACol, ARow], SourceParts[ACol, ARow],
PartSizing[ACol, ARow], (ACol = 1) and (ARow = 1));
end;
end;
end;
procedure TdxSkinImage.DrawPart(ACanvas: TdxSkinCanvas; const ADest: TRect;
const ASource: TRect; APartSizing, AIsCenterPart: Boolean);
begin
if (GradientBeginColor <> clNone) and AIsCenterPart then
ACanvas.FillRectByGradient(ADest, GradientBeginColor, GradientEndColor, Gradient)
else
if not APartSizing then
ACanvas.DrawImage(Texture, ADest, ASource)
else
if Stretch = smTile then
ACanvas.TileImage(Texture, ADest, ASource)
else
ACanvas.StretchDrawImage(Texture, ADest, ASource);
end;
procedure TdxSkinImage.DoChange;
begin
IsDirty := True;
if Assigned(FOnChange) then
FOnChange(Self);
end;
procedure TdxSkinImage.DoInitializeInfo;
var
AState: TdxSkinElementState;
AParts: TdxSkinElementPartBounds;
AStateIndices: array[TdxSkinElementState] of Byte;
begin
FStateCount := 0;
FillChar(AStateIndices, SizeOf(AStateIndices), 0);
for AState := Low(TdxSkinElementState) to High(TdxSkinElementState) do
if AState in States then
begin
AStateIndices[AState] := FStateCount;
Inc(FStateCount);
end;
FSize := cxSize(Texture.Width, Texture.Height);
if StateCount > 0 then
begin
if ImageLayout = ilHorizontal then
FSize.cx := FSize.cx div ImageCount div StateCount
else
FSize.cy := FSize.cy div ImageCount div StateCount;
end;
for AState := Low(TdxSkinElementState) to High(TdxSkinElementState) do
begin
if ImageLayout = ilHorizontal then
FStateBounds[AState] := Rect(AStateIndices[AState] * FSize.cx,
0, (AStateIndices[AState] + 1) * FSize.cx, FSize.cy)
else
FStateBounds[AState] := Rect(0, AStateIndices[AState] * FSize.cy,
FSize.cx, (AStateIndices[AState] + 1) * FSize.cy)
end;
InitializePartsInfo(Rect(0, 0, FSize.cx, FSize.cy), AParts, FPartsVisibility, False);
end;
function TdxSkinImage.GetOwner: TPersistent;
begin
Result := FOwner;
end;
procedure TdxSkinImage.InitializePartsInfo(const ABounds: TRect;
var AParts; var AVisibility; ACheckMargins: Boolean);
procedure MakePart(const ALeft, ATop, ARight, ABottom: Integer;
var ARect: TRect; var AVisible: Boolean);
begin
if not AVisible then Exit;
ARect.Left := ALeft;
ARect.Top := ATop;
ARect.Right := ARight;
ARect.Bottom := ABottom;
AVisible := (ALeft < ARight) and (ATop < ABottom);
end;
procedure DoCheckMargins(var AMargins: TRect);
var
ASize, ADelta, I: Integer;
begin
if ACheckMargins then
begin
ASize := AMargins.Left + AMargins.Right;
ADelta := ASize - cxRectWidth(ABounds);
if ADelta > 0 then
begin
for I := 0 to 2 do
begin
FPartSizing[0, I] := True;
FPartSizing[2, I] := True;
end;
Dec(AMargins.Left, MulDiv(AMargins.Left, ADelta, ASize));
Dec(AMargins.Right, MulDiv(AMargins.Right, ADelta, ASize));
end;
ASize := AMargins.Top + AMargins.Bottom;
ADelta := ASize - cxRectHeight(ABounds);
if ADelta > 0 then
begin
Dec(AMargins.Top, MulDiv(AMargins.Top, ADelta, ASize));
Dec(AMargins.Bottom, MulDiv(AMargins.Bottom, ADelta, ASize));
for I := 0 to 2 do
begin
FPartSizing[I, 0] := True;
FPartSizing[I, 2] := True;
end;
end;
end;
end;
var
AMargins, R: TRect;
begin
AMargins := Margins.Rect;
// stretch margins
Move(dxSkinsCore.PartSizing, FPartSizing, SizeOf(FPartSizing));
DoCheckMargins(AMargins);
//
with AMargins do
begin
R := cxRect(ABounds.Left + Left, ABounds.Top + Top,
ABounds.Right - Right, ABounds.Bottom - Bottom);
// check horizontal bounds
if R.Left > ABounds.Right then
R.Left := ABounds.Right;
if R.Left > R.Right then
R.Right := R.Left;
if R.Right > ABounds.Right then
R.Right := ABounds.Right;
// check vertical bounds
if R.Top > ABounds.Bottom then
R.Top := ABounds.Bottom;
if R.Top > R.Bottom then
R.Bottom := R.Top;
if R.Bottom > ABounds.Bottom then
R.Bottom := ABounds.Bottom;
end;
// top line
MakePart(ABounds.Left, ABounds.Top, R.Left, R.Top,
TdxSkinElementPartBounds(AParts)[0, 0],
TdxSkinElementPartVisibility(AVisibility)[0, 0]);
MakePart(R.Left, ABounds.Top, R.Right, R.Top,
TdxSkinElementPartBounds(AParts)[1, 0],
TdxSkinElementPartVisibility(AVisibility)[1, 0]);
MakePart(R.Right, ABounds.Top, ABounds.Right, R.
Top, TdxSkinElementPartBounds(AParts)[2, 0],
TdxSkinElementPartVisibility(AVisibility)[2, 0]);
// middle line
MakePart(ABounds.Left, R.Top, R.Left, R.Bottom,
TdxSkinElementPartBounds(AParts)[0, 1],
TdxSkinElementPartVisibility(AVisibility)[0, 1]);
MakePart(R.Left, R.Top, R.Right, R.Bottom,
TdxSkinElementPartBounds(AParts)[1, 1],
TdxSkinElementPartVisibility(AVisibility)[1, 1]);
MakePart(R.Right, R.Top, ABounds.Right, R.Bottom,
TdxSkinElementPartBounds(AParts)[2, 1],
TdxSkinElementPartVisibility(AVisibility)[2, 1]);
// bottom line
MakePart(ABounds.Left, R.Bottom, R.Left, ABounds.Bottom,
TdxSkinElementPartBounds(AParts)[0, 2],
TdxSkinElementPartVisibility(AVisibility)[0, 2]);
MakePart(R.Left, R.Bottom, R.Right, ABounds.Bottom,
TdxSkinElementPartBounds(AParts)[1, 2],
TdxSkinElementPartVisibility(AVisibility)[1, 2]);
MakePart(R.Right, R.Bottom, ABounds.Right, ABounds.Bottom,
TdxSkinElementPartBounds(AParts)[2, 2],
TdxSkinElementPartVisibility(AVisibility)[2, 2]);
end;
function TdxSkinImage.GetEmpty: Boolean;
begin
Result := (FSourceName = '') and Texture.Empty;
end;
function TdxSkinImage.GetImageCount: Integer;
begin
Result := Owner.ImageCount;
end;
function TdxSkinImage.GetName: string;
begin
if not Empty then
Result := Owner.ExpandName(Self)
else
Result := '';
end;
function TdxSkinImage.GetPartSizing(Col, Row: Integer): Boolean;
begin
Result := FPartSizing[Col, Row];
end;
function TdxSkinImage.GetPartVisible(Col, Row: Integer): Boolean;
begin
Result := FPartsVisibility[Col, Row];
end;
function TdxSkinImage.GetSize: TSize;
begin
CheckInfo;
Result := FSize;
end;
function TdxSkinImage.GetSourceName: string;
begin
Result := FSourceName;
if (Result = '') and not Empty then
Result := Owner.Path + Name;
end;
function TdxSkinImage.GetStateBounds(
AImageIndex: Integer; AState: TdxSkinElementState): TRect;
begin
CheckInfo;
Result := FStateBounds[AState];
if AImageIndex > 0 then
begin
if ImageLayout = ilHorizontal then
OffsetRect(Result, StateCount * AImageIndex * Size.cx, 0)
else
OffsetRect(Result, 0, StateCount * AImageIndex * Size.cy)
end;
end;
function TdxSkinImage.GetStateCount: Integer;
begin
CheckInfo;
Result := FStateCount;
end;
procedure TdxSkinImage.ReadData(AStream: TStream);
var
APos, ASize: Integer;
begin
AStream.Read(FMargins.Data^, SizeOf(TRect));
AStream.Read(FImageLayout, SizeOf(TdxSkinImageLayout));
AStream.Read(FStates, SizeOf(TdxSkinElementStates));
AStream.Read(FStretch, SizeOf(FStretch));
if Owner.Group.Skin.Version >= 1.02 then
begin
AStream.Read(FGradientBeginColor, SizeOf(FGradientBeginColor));
AStream.Read(FGradientEndColor, SizeOf(FGradientEndColor));
AStream.Read(FGradient, SizeOf(FGradient));
end;
AStream.Read(ASize, SizeOf(Integer));
APos := AStream.Position;
if ASize > 0 then
begin
PartStream.InitializeEx(AStream, AStream.Position, AStream.Position + ASize);
Texture.LoadFromStream(PartStream);
end;
AStream.Position := APos + ASize;
IsDirty := True;
end;
procedure TdxSkinImage.WriteData(AStream: TStream);
var
ASize: Integer;
APNGStream: TMemoryStream;
begin
AStream.Write(Margins.Data^, SizeOf(TRect));
AStream.Write(FImageLayout, SizeOf(TdxSkinImageLayout));
AStream.Write(FStates, SizeOf(TdxSkinElementStates));
AStream.Write(FStretch, SizeOf(FStretch));
AStream.Write(FGradientBeginColor, SizeOf(FGradientBeginColor));
AStream.Write(FGradientEndColor, SizeOf(FGradientEndColor));
AStream.Write(FGradient, SizeOf(FGradient));
APNGStream := TMemoryStream.Create;
try
if not Empty then
Texture.SaveToStream(APNGStream);
ASize := APNGStream.Size;
AStream.Write(ASize, SizeOf(Integer));
if ASize > 0 then
begin
APNGStream.Position := 0;
AStream.Write(APNGStream.Memory^, APNGStream.Size);
end;
finally
APNGStream.Free;
end;
end;
procedure TdxSkinImage.SetGradientBeginColor(AValue: TColor);
begin
if AValue <> FGradientBeginColor then
begin
FGradientBeginColor := AValue;
DoChange;
end;
end;
procedure TdxSkinImage.SetGradientEndColor(AValue: TColor);
begin
if AValue <> GradientEndColor then
begin
FGradientEndColor := AValue;
DoChange;
end;
end;
procedure TdxSkinImage.SetGradientMode(AValue: TdxSkinGradientMode);
begin
if AValue <> FGradient then
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?