⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sxskinradiobutton.pas

📁 skin components for design of your applicastions
💻 PAS
📖 第 1 页 / 共 4 页
字号:
           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 + -