📄 sxskinradiobutton.pas
字号:
Image:TSXSkinStyleImageElement;
AAGlyphOffset:Integer;
AATextOffset:Integer;
FTextWidth:Integer;
FTextHeight:Integer;
TH,TW:Integer;
NewWidth:Integer;
NewHeight:Integer;
procedure DoSetRBState;
begin
if not SetRBState then
GetCurrentRBState(RBState);
end;
begin
if Parent=nil then exit;
OldGlyphRect:=FGlyphRect;
OldTextRect:=FTextRect;
GlyphChanged:=False;
TextChanged:=False;
SetRBState:=False;
if Params*[rbrpGlyph,rbrpGlyphOnStyleChange,rbrpGlyphOnSizeChange]<>[] then
begin
DoSetRBState;
//
FGlyphWidth:=RBState.GlyphWidth;
FGlyphHeight:=RBState.GlyphHeight;
if (RBState.GlyphStyle<>'') and ((FGlyphWidth=0) or (FGlyphHeight=0)) then
begin
A:=SkinLibrary.Styles.GetGStyleIndex(RBState.GlyphStyle,0,0);
if A>=0 then
begin
GlyphStyle:=TSXSkinGeneralStyle(SkinLibrary.Styles[A]);
for B:=0 to GlyphStyle.Elements.Count-1 do
if GlyphStyle.Elements[B] is TSXSkinStyleImageElement then
begin
Image:=TSXSkinStyleImageElement(GlyphStyle.Elements[B]);
Image.ValidateBitmap(SkinLibrary);
if Image.Bitmap<>nil then
begin
if FGlyphWidth=0 then FGlyphWidth:=Image.Bitmap.Width;
if FGlyphHeight=0 then FGlyphHeight:=Image.Bitmap.Height;
end;
end;
end;
end;
//
if rbrpGlyph in Params then GlyphChanged:=True else
begin
if rbrpGlyphOnSizeChange in Params then
GlyphChanged:=(FGlyphWidth<>FGlyphRect.Right-FGlyphRect.Left) or
(FGlyphHeight<>FGlyphRect.Bottom-FGlyphRect.Top);
if not GlyphChanged and (rbrpGlyphOnStyleChange in Params) then
GlyphChanged:=(FLastGlyphStyle<>RBState.GlyphStyle);
end;
if GlyphChanged then
FGlyphRect:=Rect(0,0,FGlyphWidth,FGlyphHeight);
FLastGlyphStyle:=RBState.GlyphStyle;
end;
if Params*[rbrpText,rbrpTextOnFontChange,rbrpTextIfWordWrap]<>[] then
begin
DoSetRBState;
if rbrpText in Params then TextChanged:=True else
if FWordWrap and (rbrpTextIfWordWrap in Params) then TextChanged:=True else
if rbrpTextOnFontChange in Params then
TextChanged:=not SameFontData(RBState.FD,FLastFontData);
if TextChanged then
begin
if FTextBitmap<>nil then
begin
FTextBitmap.Free;
FTextBitmap:=nil;
end;
FLastFontData:=RBState.FD;
Canvas.Font.Name:=RBState.FD.FontName;
Canvas.Font.Size:=RBState.FD.FontSize;
Canvas.Font.Style:=RBState.FD.FontStyle;
FTextRect:=Rect(0,0,Width,Height);
if (SkinLibrary<>nil) and SkinLibrary.CanBeUsed then
begin
A:=SkinLibrary.Styles.GetIndexByName(SkinStyle);
if (A>=0) and (SkinLibrary.Styles[A] is TSXSkinRadioButtonStyle) then
begin
case FGlyphPosition of
gpLeftTop,
gpLeft,
gpLeftBottom,
gpRightTop,
gpRight,
gpRightBottom: begin
Dec(FTextRect.Right,FGlyphRect.Right-FGlyphRect.Left);
if (FLastGlyphStyle<>'') and (Caption<>'') then
Dec(FTextRect.Right,FTextOffset);
Dec(FTextRect.Right,RBState.CaptionLeftOffset);
Dec(FTextRect.Right,RBState.CaptionRightOffset);
//
Dec(FTextRect.Bottom,RBState.CaptionTopOffset);
Dec(FTextRect.Bottom,RBState.CaptionBottomOffset);
end;
gpTop,
gpBottom: begin
Dec(FTextRect.Right,RBState.CaptionLeftOffset);
Dec(FTextRect.Right,RBState.CaptionRightOffset);
//
Dec(FTextRect.Right,FGlyphRect.Bottom-FGlyphRect.Top);
if (FLastGlyphStyle<>'') and (Caption<>'') then
Dec(FTextRect.Right,FTextOffset);
Dec(FTextRect.Bottom,RBState.CaptionTopOffset);
Dec(FTextRect.Bottom,RBState.CaptionBottomOffset);
end;
end;
Flags:=DT_NOPREFIX or DT_NOCLIP or DT_TOP or DT_CALCRECT;
case FAlignment of
taLeftJustify: Flags:=Flags or DT_LEFT;
taRightJustify: Flags:=Flags or DT_RIGHT;
taCenter: Flags:=Flags or DT_CENTER;
end;
if FWordWrap then Flags:=Flags or DT_WORDBREAK;
Dec(FTextRect.Right,RBState.TextLeftOffset+RBState.TextRightOffset);
Dec(FTextRect.Bottom,RBState.TextTopOffset+RBState.TextBottomOffset);
if RBState.FD.SmoothLevel=0 then
DrawText(Canvas.Handle,PChar(Caption),-1,FTextRect,Flags) else
DrawSmoothText(Canvas,Caption,FTextRect,Flags,RBState.FD.SmoothLevel);
Inc(FTextRect.Right,RBState.TextLeftOffset+RBState.TextRightOffset);
Inc(FTextRect.Bottom,RBState.TextTopOffset+RBState.TextBottomOffset);
FLastTextLeftOffset:=RBState.TextLeftOffset;
FLastTextTopOffset:=RBState.TextTopOffset;
FLastTextRightOffset:=RBState.TextRightOffset;
FLastTextBottomOffset:=RBState.TextBottomOffset;
end;
end;
end;
FLastFontData:=RBState.FD;
end;
//
if (SkinLibrary<>nil) and SkinLibrary.CanBeUsed then
begin
A:=SkinLibrary.Styles.GetIndexByName(SkinStyle);
if (A>=0) and (SkinLibrary.Styles[A] is TSXSkinRadioButtonStyle) then
begin
DoSetRBState;
FTextWidth:=FTextRect.Right-FTextRect.Left;
FTextHeight:=FTextRect.Bottom-FTextRect.Top;
AATextOffset:=0;
AAGlyphOffset:=0;
if FAutoAlignFirstLine and (FGlyphPosition in [gpLeftTop,gpRightTop]) and
not IsRectEmpty(FGlyphRect) then
begin
if RBState.FD.SmoothLevel=0 then
TH:=Canvas.TextHeight(Caption) else
GetRenderedTextSize(Canvas,Caption,RBState.FD.SmoothLevel,TW,TH);
AATextOffset:=(FGlyphHeight-TH) div 2-RBState.TextTopOffset;
if AATextOffset<0 then
begin
AAGlyphOffset:=-AATextOffset;
AATextOffset:=0;
end;
end else
if FGlyphPosition in [gpLeft,gpRight] then
begin
AAGlyphOffset:=(FTextHeight-FGlyphHeight) div 2;
if AAGlyphOffset<0 then
begin
AATextOffset:=-AAGlyphOffset;
AAGlyphOffset:=0;
end;
end else
if FGlyphPosition in [gpLeftBottom,gpRightBottom] then
begin
AAGlyphOffset:=FTextHeight-FGlyphHeight;
if AAGlyphOffset<0 then
begin
AATextOffset:=-AAGlyphOffset;
AAGlyphOffset:=0;
end;
end;
//
NewWidth:=Width; NewHeight:=Height;
if FAutoSizeWidth or FAutoSizeHeight then
begin
case FGlyphPosition of
gpLeftTop,
gpLeft,
gpLeftBottom,
gpRightTop,
gpRight,
gpRightBottom: begin
NewWidth:=FGlyphWidth+FTextWidth+FTextOffset+
RBState.CaptionLeftOffset+
RBState.CaptionRightOffset;
NewHeight:=RBState.CaptionTopOffset+
RBState.CaptionBottomOffset+
Max(FGlyphHeight+AAGlyphOffset,FTextHeight+AATextOffset);
end;
gpTop,
gpBottom: begin
NewWidth:=RBState.CaptionLeftOffset+
RBState.CaptionRightOffset+
Max(FGlyphWidth,FTextWidth);
NewHeight:=RBState.CaptionTopOffset+
RBState.CaptionBottomOffset+FTextOffset+
FGlyphHeight+FTextHeight;
end;
end;
if not FAutoSizeWidth then NewWidth:=Width;
if not FAutoSizeHeight then NewHeight:=Height;
end;
//
case FGlyphPosition of
gpLeftTop,
gpLeft,
gpLeftBottom: begin
FGlyphRect.Left:=RBState.CaptionLeftOffset;
FGlyphRect.Top:=RBState.CaptionTopOffset+AAGlyphOffset;
//
FTextRect.Left:=FGlyphRect.Left+FGlyphWidth+FTextOffset;
FTextRect.Top:=RBState.CaptionTopOffset+AATextOffset;
end;
gpTop: begin
FGlyphRect.Left:=(NewWidth-FGlyphWidth+RBState.CaptionLeftOffset-RBState.CaptionRightOffset) div 2;
FGlyphRect.Top:=RBState.CaptionTopOffset;
//
FTextRect.Left:=(NewWidth-FTextWidth+RBState.CaptionLeftOffset-RBState.CaptionRightOffset) div 2;
FTextRect.Top:=FGlyphRect.Top+FGlyphHeight+FTextOffset;
end;
gpRightTop,
gpRight,
gpRightBottom: begin
FTextRect.Left:=RBState.CaptionLeftOffset;
FTextRect.Top:=RBState.CaptionTopOffset+AATextOffset;
//
FGlyphRect.Left:=FTextRect.Left+FTextWidth+FTextOffset;
FGlyphRect.Top:=RBState.CaptionTopOffset+AAGlyphOffset;
end;
gpBottom: begin
FTextRect.Left:=(NewWidth-FTextWidth+RBState.CaptionLeftOffset-RBState.CaptionRightOffset) div 2;
FTextRect.Top:=RBState.CaptionTopOffset;
//
FGlyphRect.Left:=(NewWidth-FGlyphWidth+RBState.CaptionLeftOffset-RBState.CaptionRightOffset) div 2;
FGlyphRect.Top:=FTextRect.Top+FTextHeight+FTextOffset;
end;
end;
FGlyphRect.Right:=FGlyphRect.Left+FGlyphWidth;
FGlyphRect.Bottom:=FGlyphRect.Top+FGlyphHeight;
FTextRect.Right:=FTextRect.Left+FTextWidth;
FTextRect.Bottom:=FTextRect.Top+FTextHeight;
//
if (Width<>NewWidth) or (Height<>NewHeight) then
InternalSetBounds(Left,Top,NewWidth,NewHeight);
if not FAutoSizeHeight and (FVerticalAlignment<>taAlignTop) then
begin
Offset:=0;
case FVerticalAlignment of
taVerticalCenter: Offset:=(Height-Max(FGlyphRect.Bottom,FTextRect.Bottom)-
Min(FGlyphRect.Top,FTextRect.Top)) div 2;
taAlignBottom: Offset:=Height-Max(FGlyphRect.Bottom,FTextRect.Bottom)-
2*Min(FGlyphRect.Top,FTextRect.Top);
end;
Inc(FGlyphRect.Top,Offset);
Inc(FGlyphRect.Bottom,Offset);
Inc(FTextRect.Top,Offset);
Inc(FTextRect.Bottom,Offset);
end;
end;
end;
//Invalidating Regions
if GlyphChanged or not EqualRect(OldGlyphRect,FGlyphRect) then
begin
if HandleAllocated then
begin
InvalidateRect(Handle,@OldGlyphRect,False);
InvalidateRect(Handle,@FGlyphRect,False);
end;
end;
if TextChanged or not EqualRect(OldTextRect,FTextRect) then
begin
if HandleAllocated then
begin
InvalidateRect(Handle,@OldTextRect,False);
InvalidateRect(Handle,@FTextRect,False);
end;
end;
//
if rbrpInvalidateOnStyleChange in Params then
begin
DoSetRBState;
if (RBState.Style<>FLastStyle) or (RBState.OverStyle<>FLastOverStyle) then
begin
if HandleAllocated then
InvalidateRect(Handle,nil,False);
FLastStyle:=RBState.Style;
FLastOverStyle:=RBState.OverStyle;
end;
end;
end;
function TSXSkinCustomRadioButton.IsTransparent(X,Y:Integer;Limit:Integer=10):Boolean;
var A:Integer;
Style:TSXSkinGeneralStyle;
RBState:TSXSkinRadioButtonStateParam;
begin
Result:=True;
if (SkinLibrary<>nil) and SkinLibrary.CanBeUsed then
begin
GetCurrentRBState(RBState);
A:=SkinLibrary.Styles.GetGStyleIndex(RBState.Style,Width,Height);
if A>=0 then
begin
Style:=TSXSkinGeneralStyle(SkinLibrary.Styles[A]);
Result:=Style.IsTransparent(Self,CEID_Back,X,Y,Width,Height,SkinLibrary,Limit,VComparer);
end;
if Result then
begin
A:=SkinLibrary.Styles.GetGStyleIndex(RBState.OverStyle,Width,Height);
if A>=0 then
begin
Style:=TSXSkinGeneralStyle(SkinLibrary.Styles[A]);
Result:=Style.IsTransparent(Self,CEID_Back,X,Y,Width,Height,SkinLibrary,Limit,VComparer);
end;
end;
if Result then
begin
A:=SkinLibrary.Styles.GetGStyleIndex(RBState.GlyphStyle,Width,Height);
if A>=0 then
begin
Style:=TSXSkinGeneralStyle(SkinLibrary.Styles[A]);
Result:=Style.IsTransparent(Self,CEID_Glyph,X,Y,Width,Height,SkinLibrary,Limit);
end;
end;
end;
end;
function TSXSkinCustomRadioButton.CapturesMouseAt(X,Y:Integer):Boolean;
var A:Integer;
Style:TSXSkinGeneralStyle;
RBState:TSXSkinRadioButtonStateParam;
begin
Result:=True;
if (SkinLibrary<>nil) and SkinLibrary.CanBeUsed then
begin
GetCurrentRBState(RBState);
A:=SkinLibrary.Styles.GetGStyleIndex(RBState.Style,Width,Height);
if A>=0 then
begin
Style:=TSXSkinGeneralStyle(SkinLibrary.Styles[A]);
Result:=Style.CapturesMouseAt(Self,CEID_Back,X,Y,Width,Height,SkinLibrary,VComparer);
end;
if not Result then
begin
A:=SkinLibrary.Styles.GetGStyleIndex(RBState.OverStyle,Width,Height);
if A>=0 then
begin
Style:=TSXSkinGeneralStyle(SkinLibrary.Styles[A]);
Result:=Style.CapturesMouseAt(Self,CEID_Back,X,Y,Width,Height,SkinLibrary,VComparer);
end;
end;
if not Result then
begin
A:=SkinLibrary.Styles.GetGStyleIndex(RBState.GlyphStyle,FGlyphRect.Right-FGlyphRect.Left,FGlyphRect.Bottom-FGlyphRect.Top);
if A>=0 then
begin
Style:=TSXSkinGeneralStyle(SkinLibrary.Styles[A]);
Result:=Style.CapturesMouseAt(Self,CEID_Glyph,X-FGlyphRect.Left,Y-FGlyphRect.Top,
FGlyphRect.Right-FGlyphRect.Left,FGlyphRect.Bottom-FGlyphRect.Top,
SkinLibrary);
end;
end;
end;
end;
constructor TSXSkinCustomRadioButton.Create(AOwner:TComponent);
begin
inherited Create(AOwner);
CEID_Back:=GetNewCElementID;
CEID_Glyph:=GetNewCElementID;
VComparer:=TSXRadioButtonVariableComparer.Create;
VComparer.Control:=Self;
VComparer.OnGetVariable:=OnGetVariable;
ControlStyle:=ControlStyle+[csSetCaption]-[csDoubleClicks];
FAutoSizeWidth:=True;
FAutoSizeHeight:=True;
FAutoAlignFirstLine:=True;
FTextOffset:=2;
FGlyphPosition:=gpLeftTop;
SkinStyle:='_RadioButton';
TabStop:=True;
end;
destructor TSXSkinCustomRadioButton.Destroy;
begin
FThread.Free;
FTextBitmap.Free;
FLastGlyph.Free;
FLastRadioButton.Free;
inherited;
VComparer.Free;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -